General Setup


Create a new analysis directories.

- general directory

- for plots

- for output of summary results

- for baseline tables

- for genetic analyses

- for Cox regression results
source("scripts/functions.R")
source("scripts/pack03.packages.R")
Update all/some/none? [a/s/n]: 
n
Today = format(as.Date(as.POSIXlt(Sys.time())), "%Y%m%d")
Today.Report = format(as.Date(as.POSIXlt(Sys.time())), "%A, %B %d, %Y")
source("scripts/colors.R")

ERA-CVD ‘druggable-MI-targets’

For the ERA-CVD ‘druggable-MI-targets’ project (grantnumber: 01KL1802) we performed two related RNA sequencing (RNAseq) experiments:

  1. conventional (‘bulk’) RNAseq using RNA extracted from carotid plaque samples, n ± 700. As of Thursday, October 31, 2024 all samples have been selected and RNA has been extracted; quality control (QC) was performed and we have a dataset of 635 samples.

  2. single-cell RNAseq (scRNAseq) of at least n = 40 samples (20 females, 20 males). As of Thursday, October 31, 2024 data is available of 40 samples (3 females, 15 males), we are extending sampling to get more female samples.

Plaque samples are derived from carotid endarterectomies as part of the Athero-Express Biobank Study which is an ongoing study in the UMC Utrecht.

Background

Here we map the MR_CVD_MDD to single-cells from the plaques.

Targets

Here we obtain data from the MR_CVD_MDD in plaques.

library(openxlsx)

gene_list_df <- read.xlsx(paste0(PROJECT_loc, "/targets/targets.xlsx"), sheet = "Genes")

gene_list <- unlist(gene_list_df$Gene)
gene_list
 [1] "ADAP1"   "BAHD1"   "CHAF1A"  "DISP2"   "FAM98B"  "GNA11"   "GPR176"  "KNL1"    "MDFIC"   "MPND"    "NDUFA11" "PIP5K1C" "SUN1"    "TLE5"    "ZFAND2A"

Load data

First we will load the data:

  • scRNAseq experimental data and rename the cell types.
  • Athero-Express clinical data.

Here we load the latest dataset from our Athero-Express single-cell RNA experiment.


# load(paste0(AESCRNA_loc, "/20210811.46.patients.KP.RData"))
# scRNAseqData <- seuset
# rm(seuset)
# 
# saveRDS(scRNAseqData, paste0(AESCRNA_loc, "/20210811.46.patients.KP.RDS"))

scRNAseqData <- readRDS(paste0(AESCRNA_loc, "/20210811.46.patients.KP.RDS"))

scRNAseqData
An object of class Seurat 
36147 features across 4948 samples within 2 assays 
Active assay: RNA (20111 features, 0 variable features)
 3 layers present: counts, data, scale.data
 1 other assay present: SCT
 2 dimensional reductions calculated: pca, umap

The naming/classification is based on a combination conventional markers. We do not claim to know the exact identity of each cell, rather we refer to cells as ‘KIT+ Mast cells”-like cells. Likewise we refer to the cell clusters as ’communities’ of cells that exhibit similar properties, i.e. similar defining markers (e.g. KIT).

We will rename the cell types to human readable names.

### change names for clarity
backup.scRNAseqData = scRNAseqData
# get the old names to change to new names
UMAPPlot(scRNAseqData, label = FALSE, pt.size = 1.25, label.size = 4, group.by = "ident")

unique(scRNAseqData@active.ident)
 [1] CD3+ T Cells I                                 CD3+ T Cells IV                                CD34+ Endothelial Cells I                     
 [4] CD3+ T Cells V                                 CD3+CD56+ NK Cells II                          CD3+ T Cells VI                               
 [7] CD68+IL18+TLR4+TREM2+ Resident macrophages     CD3+CD56+ NK Cells I                           ACTA2+ Smooth Muscle Cells                    
[10] CD3+ T Cells II                                FOXP3+ T Cells                                 CD34+ Endothelial Cells II                    
[13] CD3+ T Cells III                               CD68+CD1C+ Dendritic Cells                     CD68+CASP1+IL1B+SELL+ Inflammatory macrophages
[16] CD79A+ Class-switched Memory B Cells           CD68+ABCA1+OLR1+TREM2+ Foam Cells              CD68+KIT+ Mast Cells                          
[19] CD68+CD4+ Monocytes                            CD79+ Plasma B Cells                          
20 Levels: CD3+ T Cells I CD3+ T Cells II CD3+ T Cells III CD3+ T Cells IV CD68+IL18+TLR4+TREM2+ Resident macrophages ... CD79+ Plasma B Cells
celltypes <- c("CD68+CD4+ Monocytes" = "CD68+CD4+ Mono", 
               "CD68+IL18+TLR4+TREM2+ Resident macrophages" = "CD68+IL18+TLR4+TREM2+ MRes", 
               "CD68+CD1C+ Dendritic Cells" = "CD68+CD1C+ DC",
               "CD68+CASP1+IL1B+SELL+ Inflammatory macrophages" = "CD68+CASP1+IL1B+SELL MInf",
               "CD68+ABCA1+OLR1+TREM2+ Foam Cells" = "CD68+ABCA1+OLR1+TREM2+ FC",
               
               # T-cells
               "CD3+ T Cells I" = "CD3+ TC I",
               "CD3+ T Cells II" = "CD3+ TC II", 
               "CD3+ T Cells III" = "CD3+ TC III", 
               "CD3+ T Cells IV" = "CD3+ TC IV", 
               "CD3+ T Cells V" = "CD3+ TC V", 
               "CD3+ T Cells VI" = "CD3+ TC VI", 
               "FOXP3+ T Cells" = "FOXP3+ TC",
               
               # Endothelial cells
               "CD34+ Endothelial Cells I" = "CD34+ EC I", 
               "CD34+ Endothelial Cells II" = "CD34+ EC II", 
               
               # SMC
               "ACTA2+ Smooth Muscle Cells" = "ACTA2+ SMC", 
               
               # NK Cells
               "CD3+CD56+ NK Cells I" = "CD3+CD56+ NK I",
               "CD3+CD56+ NK Cells II" = "CD3+CD56+ NK II",
               # Mast
               "CD68+KIT+ Mast Cells" = "CD68+KIT+ MC",
               
               "CD79A+ Class-switched Memory B Cells" = "CD79A+ BCmem", 
               "CD79+ Plasma B Cells" = "CD79+ BCplasma")

scRNAseqData <- Seurat::RenameIdents(object = scRNAseqData, 
                                       celltypes)
UMAPPlot(scRNAseqData, label = TRUE, pt.size = 1.25, label.size = 4, group.by = "ident",
         repel = TRUE)

Clinical data

Loading the Athero-Express clinical data.

AEDB.CEA <- readRDS(file = paste0(OUT_loc, "/", Today,".",PROJECTNAME,".AEDB.CEA.RDS"))
# AEDB.CEA <- readRDS(file = paste0(OUT_loc, "/20240531.",PROJECTNAME,".AEDB.CEA.RDS"))
# Baseline table variables
basetable_vars = c("Hospital", "ORyear", "Artery_summary",
                   "Age", "Gender", 
                   # "TC_finalCU", "LDL_finalCU", "HDL_finalCU", "TG_finalCU", 
                   "TC_final", "LDL_final", "HDL_final", "TG_final", 
                   # "hsCRP_plasma",
                   "systolic", "diastoli", "GFR_MDRD", "BMI", 
                   "KDOQI", "BMI_WHO",
                   "SmokerStatus", "AlcoholUse",
                   "DiabetesStatus", 
                   "Hypertension.selfreport", "Hypertension.selfreportdrug", "Hypertension.composite", "Hypertension.drugs", 
                   "Med.anticoagulants", "Med.all.antiplatelet", "Med.Statin.LLD", 
                   "Stroke_Dx", "sympt", "Symptoms.5G", "AsymptSympt", "AsymptSympt2G",
                   "Symptoms.Update2G", "Symptoms.Update3G", "indexsymptoms_latest_4g",
                   "restenos", "stenose", 
                   "CAD_history", "PAOD", "Peripheral.interv", 
                   "EP_composite", "EP_composite_time", "EP_major", "EP_major_time",
                   "MAC_rankNorm", "SMC_rankNorm", "Macrophages.bin", "SMC.bin",
                   "Neutrophils_rankNorm", "MastCells_rankNorm",
                   "IPH.bin", "VesselDensity_rankNorm",
                   "Calc.bin", "Collagen.bin", 
                   "Fat.bin_10", "Fat.bin_40", "OverallPlaquePhenotype", "Plaque_Vulnerability_Index",
                   "PCSK9_plasma", "PCSK9_plasma_rankNorm")

basetable_bin = c("Gender",  "Artery_summary",
                  "KDOQI", "BMI_WHO",
                  "SmokerStatus", "AlcoholUse",
                  "DiabetesStatus", 
                  "Hypertension.selfreport", "Hypertension.selfreportdrug", "Hypertension.composite", "Hypertension.drugs", 
                  "Med.anticoagulants", "Med.all.antiplatelet", "Med.Statin.LLD", 
                  "Stroke_Dx", "sympt", "Symptoms.5G", "AsymptSympt", "AsymptSympt2G",
                  "Symptoms.Update2G", "Symptoms.Update3G", "indexsymptoms_latest_4g",
                  "restenos", "stenose",
                  "CAD_history", "PAOD", "Peripheral.interv", 
                  "EP_major", "EP_composite", "Macrophages.bin", "SMC.bin",
                  "IPH.bin", 
                  "Calc.bin", "Collagen.bin", 
                  "Fat.bin_10", "Fat.bin_40", "OverallPlaquePhenotype", "Plaque_Vulnerability_Index")
# basetable_bin

basetable_con = basetable_vars[!basetable_vars %in% basetable_bin]
# basetable_con

AESCRNA: baseline characteristics

Preparation

metadata <- scRNAseqData@meta.data %>% as_tibble() %>% separate(orig.ident, c("Patient", NA))
scRNAseqDataMeta <- metadata %>% distinct(Patient, .keep_all = TRUE)
distinct: removed 4,902 rows (99%), 46 rows remaining
scRNAseqDataMetaAE <- merge(scRNAseqDataMeta, AEDB.CEA, by.x = "Patient", by.y = "STUDY_NUMBER", sort = FALSE, all.x = TRUE)
dim(scRNAseqDataMetaAE)
[1]   46 1242
# Replace missing data 
# Ref: https://cran.r-project.org/web/packages/naniar/vignettes/replace-with-na.html
require(naniar)

na_strings <- c("NA", "N A", "N / A", "N/A", "N/ A", 
                "Not Available", "Not available", 
                "missing", 
                "-999", "-99", 
                "No data available/missing", "No data available/Missing")
# Then you write ~.x %in% na_strings - which reads as “does this value occur in the list of NA strings”.

scRNAseqDataMetaAE %>%
  replace_with_na_all(condition = ~.x %in% na_strings)
cat("====================================================================================================")
====================================================================================================
cat("SELECTION THE SHIZZLE")
SELECTION THE SHIZZLE
cat("- sanity checking PRIOR to selection")
- sanity checking PRIOR to selection
library(data.table)
require(labelled)
ae.gender <- to_factor(scRNAseqDataMetaAE$Gender)
ae.hospital <- to_factor(scRNAseqDataMetaAE$Hospital)
table(ae.gender, ae.hospital, dnn = c("Sex", "Hospital"), useNA = "ifany")
        Hospital
Sex      St. Antonius, Nieuwegein UMC Utrecht <NA>
  female                        0          19    0
  male                          0          26    0
  <NA>                          0           0    1
ae.artery <- to_factor(scRNAseqDataMetaAE$Artery_summary)
table(ae.artery, ae.gender, dnn = c("Sex", "Artery"), useNA = "ifany")
                                                                                         Artery
Sex                                                                                       female male <NA>
  No artery known (yet), no surgery (patient ill, died, exited study), re-numbered to AAA      0    0    0
  carotid (left & right)                                                                      19   25    0
  femoral/iliac (left, right or both sides)                                                    0    0    0
  other carotid arteries (common, external)                                                    0    1    0
  carotid bypass and injury (left, right or both sides)                                        0    0    0
  aneurysmata (carotid & femoral)                                                              0    0    0
  aorta                                                                                        0    0    0
  other arteries (renal, popliteal, vertebral)                                                 0    0    0
  femoral bypass, angioseal and injury (left, right or both sides)                             0    0    0
  <NA>                                                                                         0    0    1
ae.ic <- to_factor(scRNAseqDataMetaAE$informedconsent)
table(ae.ic, ae.gender, useNA = "ifany")
                                                                                                 ae.gender
ae.ic                                                                                             female male <NA>
  missing                                                                                              0    0    0
  no, died                                                                                             0    0    0
  yes                                                                                                  9   14    0
  yes, health treatment when possible                                                                  5    7    0
  yes, no health treatment                                                                             2    2    0
  yes, no health treatment, no commercial business                                                     1    2    0
  yes, no tissue, no commerical business                                                               0    0    0
  yes, no tissue, no questionnaires, no medical info, no commercial business                           0    0    0
  yes, no questionnaires, no health treatment, no commercial business                                  0    0    0
  yes, no questionnaires, health treatment when possible                                               0    0    0
  yes, no tissue, no questionnaires, no health treatment, no commerical business                       0    0    0
  yes, no health treatment, no medical info, no commercial business                                    0    0    0
  yes, no tissue, no questionnaires, no health treatment, no medical info, no commercial business      0    0    0
  yes, no questionnaires, no health treatment                                                          0    0    0
  yes, no tissue, no health treatment                                                                  0    0    0
  yes, no tissue, no questionnaires                                                                    0    0    0
  yes, no tissue, health treatment when possible                                                       0    0    0
  yes, no tissue                                                                                       0    0    0
  yes, no commerical business                                                                          1    1    0
  yes, health treatment when possible, no commercial business                                          0    0    0
  yes, no medical info, no commercial business                                                         0    0    0
  yes, no questionnaires                                                                               0    0    0
  yes, no tissue, no questionnaires, no health treatment, no medical info                              0    0    0
  yes, no tissue, no questionnaires, no health treatment, no commercial business                       0    0    0
  yes, no medical info                                                                                 0    0    0
  yes, no questionnaires, no commercial business                                                       0    0    0
  yes, no questionnaires, no health treatment, no medical info                                         0    0    0
  yes, no questionnaires, health treatment when possible, no commercial business                       0    0    0
  yes,  no health treatment, no medical info                                                           0    0    0
  no, doesn't want to                                                                                  0    0    0
  no, unable to sign                                                                                   0    0    0
  no, no reaction                                                                                      0    0    0
  no, lost                                                                                             0    0    0
  no, too old                                                                                          0    0    0
  yes, no medical info, health treatment when possible                                                 1    0    0
  no (never asked for IC because there was no tissue)                                                  0    0    0
  yes, no medical info, no commercial business, health treatment when possible                         0    0    0
  no, endpoint                                                                                         0    0    0
  wil niets invullen, wel alles gebruiken                                                              0    0    0
  second informed concents: yes, no commercial business                                                0    0    0
  nooit geincludeerd                                                                                   0    0    0
  yes, not outside EU                                                                                  0    0    0
  yes, no DNA                                                                                          0    0    0
  yes, no commercial business, not outside EU                                                          0    0    0
  yes, no DNA, no commercial business, not outside EU                                                  0    0    0
  <NA>                                                                                                 0    0    1
rm(ae.gender, ae.hospital, ae.artery, ae.ic)


scRNAseqDataMetaAE.all <- subset(scRNAseqDataMetaAE,
                                 (Artery_summary == "carotid (left & right)" | Artery_summary == "other carotid arteries (common, external)" ) & # we only want carotids
                                   informedconsent != "missing" & # we are really strict in selecting based on 'informed consent'!
                                   informedconsent != "no, died" &
                                   informedconsent != "yes, no tissue, no commerical business" &
                                   informedconsent != "yes, no tissue, no questionnaires, no medical info, no commercial business" &
                                   informedconsent != "yes, no tissue, no questionnaires, no health treatment, no commerical business" &
                                   informedconsent != "yes, no tissue, no questionnaires, no health treatment, no medical info, no commercial business" &
                                   informedconsent != "yes, no tissue, no health treatment" &
                                   informedconsent != "yes, no tissue, no questionnaires" &
                                   informedconsent != "yes, no tissue, health treatment when possible" &
                                   informedconsent != "yes, no tissue" &
                                   informedconsent != "yes, no tissue, no questionnaires, no health treatment, no medical info" &
                                   informedconsent != "yes, no tissue, no questionnaires, no health treatment, no commercial business" &
                                   informedconsent != "no, doesn't want to" &
                                   informedconsent != "no, unable to sign" &
                                   informedconsent != "no, no reaction" &
                                   informedconsent != "no, lost" &
                                   informedconsent != "no, too old" &
                                   informedconsent != "yes, no medical info, health treatment when possible" & 
                                   informedconsent != "no (never asked for IC because there was no tissue)" &
                                   informedconsent != "no, endpoint" &
                                   informedconsent != "nooit geincludeerd" & 
                                   informedconsent != "yes, no health treatment, no commercial business" & # IMPORTANT: since we are sharing with a commercial party
                                   informedconsent != "yes, no tissue, no commerical business" & 
                                   informedconsent != "yes, no tissue, no questionnaires, no medical info, no commercial business" & 
                                   informedconsent != "yes, no questionnaires, no health treatment, no commercial business" & 
                                   informedconsent != "yes, no tissue, no questionnaires, no health treatment, no commerical business" & 
                                   informedconsent != "yes, no health treatment, no medical info, no commercial business" & 
                                   informedconsent != "yes, no tissue, no questionnaires, no health treatment, no medical info, no commercial business" & 
                                   informedconsent != "yes, no commerical business" & 
                                   informedconsent != "yes, health treatment when possible, no commercial business" & 
                                   informedconsent != "yes, no medical info, no commercial business" & 
                                   informedconsent != "yes, no tissue, no questionnaires, no health treatment, no commercial business" & 
                                   informedconsent != "yes, no questionnaires, no commercial business" & 
                                   informedconsent != "yes, no questionnaires, health treatment when possible, no commercial business" & 
                                   informedconsent != "second informed concents: yes, no commercial business")
# scRNAseqDataMetaAE.all[1:10, 1:10]
dim(scRNAseqDataMetaAE.all)
[1]   39 1242
# DT::datatable(scRNAseqDataMetaAE.all)

Baseline

Showing the baseline table for the scRNAseq data in 39 CEA patients with informed consent.

cat("===========================================================================================")
===========================================================================================
cat("CREATE BASELINE TABLE")
CREATE BASELINE TABLE
# Create baseline tables
# http://rstudio-pubs-static.s3.amazonaws.com/13321_da314633db924dc78986a850813a50d5.html
scRNAseqDataMetaAE.all.tableOne = print(CreateTableOne(vars = basetable_vars, 
                                                  # factorVars = basetable_bin,
                                                  # strata = "Gender",
                                                  data = scRNAseqDataMetaAE.all, includeNA = TRUE), 
                                   nonnormal = c(), 
                                   quote = FALSE, showAllLevels = TRUE,
                                   format = "p", 
                                   contDigits = 3)[,1:2]
Warning: These variables only have NA/NaN: Symptoms.Update2G Symptoms.Update3G indexsymptoms_latest_4g MAC_rankNorm SMC_rankNorm Neutrophils_rankNorm MastCells_rankNorm VesselDensity_rankNorm PCSK9_plasma PCSK9_plasma_rankNorm  Dropped
                                 
                                  level                                                                                   Overall         
  n                                                                                                                            39         
  Hospital (%)                    St. Antonius, Nieuwegein                                                                    0.0         
                                  UMC Utrecht                                                                               100.0         
  ORyear (%)                      No data available/missing                                                                   0.0         
                                  2002                                                                                        0.0         
                                  2003                                                                                        0.0         
                                  2004                                                                                        0.0         
                                  2005                                                                                        0.0         
                                  2006                                                                                        0.0         
                                  2007                                                                                        0.0         
                                  2008                                                                                        0.0         
                                  2009                                                                                        0.0         
                                  2010                                                                                        0.0         
                                  2011                                                                                        0.0         
                                  2012                                                                                        0.0         
                                  2013                                                                                        0.0         
                                  2014                                                                                        0.0         
                                  2015                                                                                        0.0         
                                  2016                                                                                        0.0         
                                  2017                                                                                        0.0         
                                  2018                                                                                       51.3         
                                  2019                                                                                       35.9         
                                  2020                                                                                       10.3         
                                  2021                                                                                        2.6         
                                  2022                                                                                        0.0         
  Artery_summary (%)              No artery known (yet), no surgery (patient ill, died, exited study), re-numbered to AAA     0.0         
                                  carotid (left & right)                                                                     97.4         
                                  femoral/iliac (left, right or both sides)                                                   0.0         
                                  other carotid arteries (common, external)                                                   2.6         
                                  carotid bypass and injury (left, right or both sides)                                       0.0         
                                  aneurysmata (carotid & femoral)                                                             0.0         
                                  aorta                                                                                       0.0         
                                  other arteries (renal, popliteal, vertebral)                                                0.0         
                                  femoral bypass, angioseal and injury (left, right or both sides)                            0.0         
  Age (mean (SD))                                                                                                          72.077 (8.183) 
  Gender (%)                      female                                                                                     41.0         
                                  male                                                                                       59.0         
  TC_final (mean (SD))                                                                                                      4.533 (1.252) 
  LDL_final (mean (SD))                                                                                                     2.676 (1.013) 
  HDL_final (mean (SD))                                                                                                     1.135 (0.229) 
  TG_final (mean (SD))                                                                                                      1.927 (1.093) 
  systolic (mean (SD))                                                                                                    150.842 (27.013)
  diastoli (mean (SD))                                                                                                     79.711 (16.432)
  GFR_MDRD (mean (SD))                                                                                                     79.036 (31.777)
  BMI (mean (SD))                                                                                                          26.332 (3.962) 
  KDOQI (%)                       No data available/missing                                                                   0.0         
                                  Normal kidney function                                                                     28.2         
                                  CKD 2 (Mild)                                                                               33.3         
                                  CKD 3 (Moderate)                                                                           28.2         
                                  CKD 4 (Severe)                                                                              0.0         
                                  CKD 5 (Failure)                                                                             0.0         
                                  <NA>                                                                                       10.3         
  BMI_WHO (%)                     No data available/missing                                                                   0.0         
                                  Underweight                                                                                 2.6         
                                  Normal                                                                                     33.3         
                                  Overweight                                                                                 38.5         
                                  Obese                                                                                      17.9         
                                  <NA>                                                                                        7.7         
  SmokerStatus (%)                Current smoker                                                                             28.2         
                                  Ex-smoker                                                                                  53.8         
                                  Never smoked                                                                               12.8         
                                  <NA>                                                                                        5.1         
  AlcoholUse (%)                  No                                                                                         38.5         
                                  Yes                                                                                        53.8         
                                  <NA>                                                                                        7.7         
  DiabetesStatus (%)              Control (no Diabetes Dx/Med)                                                               71.8         
                                  Diabetes                                                                                   28.2         
  Hypertension.selfreport (%)     No data available/missing                                                                   0.0         
                                  no                                                                                          7.7         
                                  yes                                                                                        87.2         
                                  <NA>                                                                                        5.1         
  Hypertension.selfreportdrug (%) No data available/missing                                                                   0.0         
                                  no                                                                                          7.7         
                                  yes                                                                                        87.2         
                                  <NA>                                                                                        5.1         
  Hypertension.composite (%)      No data available/missing                                                                   0.0         
                                  no                                                                                          7.7         
                                  yes                                                                                        92.3         
  Hypertension.drugs (%)          No data available/missing                                                                   0.0         
                                  no                                                                                         10.3         
                                  yes                                                                                        84.6         
                                  <NA>                                                                                        5.1         
  Med.anticoagulants (%)          No data available/missing                                                                   0.0         
                                  no                                                                                         87.2         
                                  yes                                                                                         5.1         
                                  <NA>                                                                                        7.7         
  Med.all.antiplatelet (%)        No data available/missing                                                                   0.0         
                                  no                                                                                         20.5         
                                  yes                                                                                        74.4         
                                  <NA>                                                                                        5.1         
  Med.Statin.LLD (%)              No data available/missing                                                                   0.0         
                                  no                                                                                         20.5         
                                  yes                                                                                        74.4         
                                  <NA>                                                                                        5.1         
  Stroke_Dx (%)                   Missing                                                                                     0.0         
                                  No stroke diagnosed                                                                        56.4         
                                  Stroke diagnosed                                                                           43.6         
  sympt (%)                       missing                                                                                     0.0         
                                  Asymptomatic                                                                               15.4         
                                  TIA                                                                                        17.9         
                                  minor stroke                                                                               25.6         
                                  Major stroke                                                                               10.3         
                                  Amaurosis fugax                                                                            15.4         
                                  Four vessel disease                                                                         0.0         
                                  Vertebrobasilary TIA                                                                        0.0         
                                  Retinal infarction                                                                          2.6         
                                  Symptomatic, but aspecific symtoms                                                          2.6         
                                  Contralateral symptomatic occlusion                                                         0.0         
                                  retinal infarction                                                                          2.6         
                                  armclaudication due to occlusion subclavian artery, CEA needed for bypass                   0.0         
                                  retinal infarction + TIAs                                                                   0.0         
                                  Ocular ischemic syndrome                                                                    7.7         
                                  ischemisch glaucoom                                                                         0.0         
                                  subclavian steal syndrome                                                                   0.0         
                                  TGA                                                                                         0.0         
  Symptoms.5G (%)                 Asymptomatic                                                                               15.4         
                                  Ocular                                                                                     23.1         
                                  Other                                                                                       2.6         
                                  Retinal infarction                                                                          5.1         
                                  Stroke                                                                                     35.9         
                                  TIA                                                                                        17.9         
  AsymptSympt (%)                 Asymptomatic                                                                               15.4         
                                  Ocular and others                                                                          30.8         
                                  Symptomatic                                                                                53.8         
  AsymptSympt2G (%)               Asymptomatic                                                                               15.4         
                                  Symptomatic                                                                                84.6         
  restenos (%)                    missing                                                                                     0.0         
                                  de novo                                                                                   100.0         
                                  restenosis                                                                                  0.0         
                                  stenose bij angioseal na PTCA                                                               0.0         
  stenose (%)                     missing                                                                                     0.0         
                                  0-49%                                                                                       2.6         
                                  50-70%                                                                                     10.3         
                                  70-90%                                                                                     46.2         
                                  90-99%                                                                                     25.6         
                                  100% (Occlusion)                                                                            0.0         
                                  NA                                                                                          0.0         
                                  50-99%                                                                                      0.0         
                                  70-99%                                                                                     15.4         
                                  99                                                                                          0.0         
  CAD_history (%)                 Missing                                                                                     0.0         
                                  No history CAD                                                                             79.5         
                                  History CAD                                                                                20.5         
  PAOD (%)                        missing/no data                                                                             0.0         
                                  no                                                                                         84.6         
                                  yes                                                                                        15.4         
  Peripheral.interv (%)           no                                                                                         76.9         
                                  yes                                                                                        23.1         
  EP_composite (%)                No data available.                                                                          0.0         
                                  No composite endpoints                                                                     79.5         
                                  Composite endpoints                                                                        17.9         
                                  <NA>                                                                                        2.6         
  EP_composite_time (mean (SD))                                                                                             2.459 (1.124) 
  EP_major (%)                    No data available.                                                                          0.0         
                                  No major events (endpoints)                                                                87.2         
                                  Major events (endpoints)                                                                   10.3         
                                  <NA>                                                                                        2.6         
  EP_major_time (mean (SD))                                                                                                 2.588 (1.111) 
  Macrophages.bin (%)             no/minor                                                                                   20.5         
                                  moderate/heavy                                                                             64.1         
                                  <NA>                                                                                       15.4         
  SMC.bin (%)                     no/minor                                                                                   20.5         
                                  moderate/heavy                                                                             64.1         
                                  <NA>                                                                                       15.4         
  IPH.bin (%)                     no                                                                                         17.9         
                                  yes                                                                                        66.7         
                                  <NA>                                                                                       15.4         
  Calc.bin (%)                    no/minor                                                                                   38.5         
                                  moderate/heavy                                                                             46.2         
                                  <NA>                                                                                       15.4         
  Collagen.bin (%)                no/minor                                                                                    7.7         
                                  moderate/heavy                                                                             71.8         
                                  <NA>                                                                                       20.5         
  Fat.bin_10 (%)                   <10%                                                                                      25.6         
                                   >10%                                                                                      59.0         
                                  <NA>                                                                                       15.4         
  Fat.bin_40 (%)                  <40%                                                                                       56.4         
                                  >40%                                                                                       28.2         
                                  <NA>                                                                                       15.4         
  OverallPlaquePhenotype (%)      atheromatous                                                                               28.2         
                                  fibroatheromatous                                                                          30.8         
                                  fibrous                                                                                    25.6         
                                  <NA>                                                                                       15.4         
  Plaque_Vulnerability_Index (%)  0                                                                                          15.4         
                                  1                                                                                          20.5         
                                  2                                                                                          15.4         
                                  3                                                                                          33.3         
                                  4                                                                                          10.3         
                                  5                                                                                           5.1         

Writing the baseline table to Excel format.

# Write basetable
require(openxlsx)
# write.xlsx(file = paste0(BASELINE_loc, "/",Today,".",PROJECTNAME,".AESCRNA.32pts.after_qc.IC_commercial.BaselineTable.xlsx"), 
#            format(as.data.frame(scRNAseqDataMetaAE.all.tableOne), digits = 5, scientific = FALSE),
#            rowNames = TRUE, colNames = TRUE, 
#            sheetName = "AESCRNA", overwrite = TRUE)
write.xlsx(file = paste0(BASELINE_loc, "/",Today,".",PROJECTNAME,".AESCRNA.CEA.39pts.after_qc.IC_academic.BaselineTable.xlsx"),
           format(as.data.frame(scRNAseqDataMetaAE.all.tableOne), digits = 5, scientific = FALSE),
           rowNames = TRUE, colNames = TRUE,
           sheetName = "AESCRNA_CEA", overwrite = TRUE)

Subset scRNAseq data

List of samples to be included based on informed consent (see above).

samples_of_interest <- unlist(scRNAseqDataMetaAE.all$Patient)
samples_of_interest
 [1] "4440" "4447" "4443" "4450" "4453" "4470" "4459" "4458" "4455" "4487" "4472" "4480" "4477" "4448" "4486" "4488" "4502" "4500" "4501" "4530" "4541" "4542"
[23] "4513" "4535" "4546" "4545" "4571" "4489" "4491" "4495" "4496" "4521" "4520" "4580" "4602" "4605" "4601" "4676" "4653"

Just make sure to keep the rows (patientid.plateid.cellid) in the data, so we will create a new column for that.

scRNAseqData$cell.ident <- rownames(scRNAseqData[[]])

Subsetting the samples of interest based on samples_of_interest.

scRNAseqDataCEA39 <- subset(scRNAseqData, subset = Patient %in% samples_of_interest)

Selecting the clinical data of interest.

variables_of_interest <- c("Hospital", "ORyear", "Artery_summary",
                           "Age", "Gender",
                           "TC_final", "LDL_final", "HDL_final", "TG_final",
                           "systolic", "diastoli", "GFR_MDRD", "BMI",
                           "KDOQI", "BMI_WHO",
                           "SmokerStatus", "AlcoholUse",
                           "DiabetesStatus",
                           "Hypertension.selfreport", "Hypertension.selfreportdrug", "Hypertension.composite", "Hypertension.drugs",
                           "Med.anticoagulants", "Med.all.antiplatelet", "Med.Statin.LLD",
                           "Stroke_Dx",
                           "sympt", "Symptoms.5G", "AsymptSympt", "AsymptSympt2G",
                           "Symptoms.Update2G", "Symptoms.Update3G", "indexsymptoms_latest_4g",
                           "restenos", "stenose",
                           "CAD_history", "PAOD", "Peripheral.interv",
                           "EP_composite", "EP_composite_time", "EP_major", "EP_major_time")

temp <- subset(scRNAseqDataMetaAE.all, select = c("Patient", variables_of_interest))

Now we are merging in the clinical data of interest.

# Step 1: Extract original metadata from Seurat object
original_metadata_df <- scRNAseqDataCEA39@meta.data

# Step 2: Merge with dataframe (temp) with select variables based on 'Patient' column
merged_metadata_df <- merge(original_metadata_df, temp, by = "Patient", all.x = TRUE, sort = FALSE)

# Step 3: Exclude already existing columns to avoid duplication
new_metadata_columns <- setdiff(colnames(temp), colnames(original_metadata_df))
new_meta_info_df <- merged_metadata_df[, new_metadata_columns, drop = FALSE]

# Step 4: Add the new metadata to the Seurat object
scRNAseqDataCEA39 <- AddMetaData(scRNAseqDataCEA39, metadata = new_meta_info_df)

# Step 5: Rename `Patient` to `STUDY_NUMBER` to match the clinical data
scRNAseqDataCEA39@meta.data <- dplyr::rename(scRNAseqDataCEA39@meta.data, "STUDY_NUMBER" = "Patient")

# Verify that the new metadata was added correctly
head(scRNAseqDataCEA39@meta.data)
NA

Saving new dataset

temp2 <- as_tibble(subset(scRNAseqDataCEA39@meta.data, select = c("STUDY_NUMBER", "orig.ident", "nCount_RNA", "nFeature_RNA",
                                                                 "Plate", "Batch", "C.H", "Type", "percent.mt",
                                                                 "nCount_SCT", "nFeature_SCT", "seurat_clusters")))

# fwrite(temp2,
#        file = paste0(OUT_loc, "/", Today, ".AESCRNA.CEA.39pts.samplelist.after_qc.IC_commercial.csv"),
#        sep = ",", row.names = FALSE, col.names = TRUE,
#        showProgress = TRUE)
# rm(temp2)
# 
# temp <- dplyr::rename(temp, "STUDY_NUMBER" = "Patient")
# fwrite(temp,
#        file = paste0(OUT_loc, "/", Today, ".AESCRNA.CEA.39pts.clinicaldata.after_qc.IC_commercial.csv"),
#        sep = ",", row.names = FALSE, col.names = TRUE,
#        showProgress = TRUE)
# rm(temp)
# 
# saveRDS(scRNAseqDataCEA39, file = paste0(OUT_loc, "/", Today, ".AESCRNA.CEA.39pts.Seurat.after_qc.IC_commercial.RDS"))

fwrite(temp2,
       file = paste0(OUT_loc, "/", Today, ".AESCRNA.CEA.39pts.samplelist.after_qc.IC_academic.csv"),
       sep = ",", row.names = FALSE, col.names = TRUE,
       showProgress = TRUE)
rm(temp2)

temp <- dplyr::rename(temp, "STUDY_NUMBER" = "Patient")
fwrite(temp,
       file = paste0(OUT_loc, "/", Today, ".AESCRNA.CEA.39pts.clinicaldata.after_qc.IC_academic.csv"),
       sep = ",", row.names = FALSE, col.names = TRUE,
       showProgress = TRUE)
rm(temp)

saveRDS(scRNAseqDataCEA39, file = paste0(OUT_loc, "/", Today, ".AESCRNA.CEA.39pts.Seurat.after_qc.IC_academic.RDS"))

AESCRNA

Quality control

Here review the number of cells per sample, plate, and patients. And plot the ratio’s per sample and study number.

## check stuff
cat("\nHow many cells per type ...?")

How many cells per type ...?
sort(table(scRNAseqDataCEA39@meta.data$SCT_snn_res.1.25))

  7  14  20  16  22  23  21  12  19  18  17  15   2  10  11   9  13   5   8   4   6   3   0   1 
  0   0   0   8  17  19  23  26  55  78  94 112 172 173 176 198 199 242 243 293 297 348 831 846 
# cat("\n\nHow many cells per plate ...?")
# sort(table(scRNAseqDataCEA39@meta.data$ID))

# cat("\n\nHow many cells per type per plate ...?")
# table(scRNAseqDataCEA39@meta.data$SCT_snn_res.0.8, scRNAseqDataCEA39@meta.data$ID)

cat("\n\nHow many cells per patient ...?")


How many cells per patient ...?
sort(table(scRNAseqDataCEA39@meta.data$STUDY_NUMBER))

4530 4440 4605 4653 4472 4458 4455 4496 4601 4502 4501 4571 4448 4477 4459 4520 4602 4489 4495 4545 4480 4447 4500 4513 4535 4676 4486 4470 4487 4546 4488 4521 
   3    6    7   20   22   35   54   70   70   73   75   76   80   84   94   96   96   97  102  106  112  114  116  123  130  135  137  144  144  144  146  161 
4580 4491 4541 4450 4542 4453 4443 
 163  175  178  205  213  222  422 
cat("\n\nVisualizing these ratio's per study number and sample ...?")


Visualizing these ratio's per study number and sample ...?
UMAPPlot(scRNAseqDataCEA39, label = TRUE, pt.size = 1.25, label.size = 4, group.by = "ident",
         repel = TRUE)
ggsave(paste0(PLOT_loc, "/", Today, ".UMAP.png"), plot = last_plot())
Saving 7.29 x 4.51 in image
ggsave(paste0(PLOT_loc, "/", Today, ".UMAP.ps"), plot = last_plot())
Saving 7.29 x 4.51 in image

# barplot(prop.table(x = table(scRNAseqDataCEA39@active.ident, scRNAseqDataCEA39@meta.data$Patient)), 
#         cex.axis = 1.0, cex.names = 0.5, las = 1,
#         col = uithof_color, xlab = "study number", legend.text = FALSE, args.legend = list(x = "bottom"))
# dev.copy(pdf, paste0(QC_loc, "/", Today, ".cell_ratios_per_sample.pdf"))
# dev.off()

# barplot(prop.table(x = table(scRNAseqDataCEA39@active.ident, scRNAseqDataCEA39@meta.data$ID)), 
#         cex.axis = 1.0, cex.names = 0.5, las = 2,
#         col = uithof_color, xlab = "sample ID", legend.text = FALSE, args.legend = list(x = "bottom"))
# dev.copy(pdf, paste0(QC_loc, "/", Today, ".cell_ratios_per_sample_per_plate.pdf"))
# dev.off()

Visualisations

Feature plots of known cellular markers

Let’s project known cellular markers.

UMAPPlot(scRNAseqDataCEA39, label = FALSE, pt.size = 1.25, label.size = 4, group.by = "ident",
         repel = TRUE)


# endothelial cells
FeaturePlot(scRNAseqDataCEA39, features = c("CD34"), cols =  c("#ECECEC", "#DB003F"))

FeaturePlot(scRNAseqDataCEA39, features = c("EDN1"), cols =  c("#ECECEC", "#DB003F"))

FeaturePlot(scRNAseqDataCEA39, features = c("EDNRA", "EDNRB"), cols =  c("#ECECEC", "#DB003F"))

FeaturePlot(scRNAseqDataCEA39, features = c("CDH5", "PECAM1"), cols =  c("#ECECEC", "#DB003F"))

FeaturePlot(scRNAseqDataCEA39, features = c("ACKR1"), cols =  c("#ECECEC", "#DB003F"))


# SMC
FeaturePlot(scRNAseqDataCEA39, features = c("MYH11"), cols =  c("#ECECEC", "#DB003F"))

FeaturePlot(scRNAseqDataCEA39, features = c("LGALS3", "ACTA2"), cols =  c("#ECECEC", "#DB003F"))


# macrophages
FeaturePlot(scRNAseqDataCEA39, features = c("CD14", "CD68"), cols =  c("#ECECEC", "#DB003F"))

FeaturePlot(scRNAseqDataCEA39, features = c("CD36"), cols =  c("#ECECEC", "#DB003F"))


# t-cells
FeaturePlot(scRNAseqDataCEA39, features = c("CD3E"), cols =  c("#ECECEC", "#DB003F"))

FeaturePlot(scRNAseqDataCEA39, features = c("CD4"), cols =  c("#ECECEC", "#DB003F"))

# FeaturePlot(scRNAseqDataCEA39, features = c("CD8"), cols =  c("#ECECEC", "#DB003F"))

# b-cells
FeaturePlot(scRNAseqDataCEA39, features = c("CD79A"), cols =  c("#ECECEC", "#DB003F"))


# mast cells
FeaturePlot(scRNAseqDataCEA39, features = c("KIT"), cols =  c("#ECECEC", "#DB003F"))


# NK cells
FeaturePlot(scRNAseqDataCEA39, features = c("NCAM1"), cols =  c("#ECECEC", "#DB003F"))

Targets of interest:

We check whether the targets genes were sequenced using our method. In case some genes are not available in our data we could filter them here.

target_genes <- gene_list
target_genes
 [1] "ADAP1"   "BAHD1"   "CHAF1A"  "DISP2"   "FAM98B"  "GNA11"   "GPR176"  "KNL1"    "MDFIC"   "MPND"    "NDUFA11" "PIP5K1C" "SUN1"    "TLE5"    "ZFAND2A"

Here we filter - if needed - genes not present in the data; all genes are present though.


gene_list_rm <- c("") 

temp = target_genes[!target_genes %in% gene_list_rm]

target_genes_qc <- c(temp)

# gene_list_qc <- gene_list
# 
# for debug
# gene_list_qc_replace <- c("MRTFA")

# target_genes_qc <- target_genes
target_genes_qc
 [1] "ADAP1"   "BAHD1"   "CHAF1A"  "DISP2"   "FAM98B"  "GNA11"   "GPR176"  "KNL1"    "MDFIC"   "MPND"    "NDUFA11" "PIP5K1C" "SUN1"    "TLE5"    "ZFAND2A"

Expression in cell communities

library(RColorBrewer)

p1 <- DotPlot(scRNAseqDataCEA39, 
              features = target_genes_qc,
              cols = "RdBu") + 
  theme(axis.text.x = element_text(angle = 45, hjust=1, size = 8)) +
  theme(axis.title.x = element_blank(), axis.title.y = element_blank()) # remove the y- and x-axis labels

p1

ggsave(paste0(PLOT_loc, "/", Today, ".DotPlot.Targets.png"), plot = last_plot())
ggsave(paste0(PLOT_loc, "/", Today, ".DotPlot.Targets.ps"), plot = last_plot())
ggsave(paste0(PLOT_loc, "/", Today, ".DotPlot.Targets.pdf"), plot = last_plot())


rm(p1)

Let’s group this dotplot based on some grouping.

If we want we can also filter the genes that are not found in the data.

# Assuming 'gene_list_df' is your data.frame with the relevant columns loaded
gene_list_df_filtered <- subset(gene_list_df, Comments != "not found" | is.na(Comments))
gene_list_df_filtered

Expression in cell communities grouped

# Separate genes by significance
gene_list_df_filtered_up <- gene_list_df_filtered$GeneSymbol[gene_list_df_filtered$Group == "UP"]
gene_list_df_filtered_down <- gene_list_df_filtered$GeneSymbol[gene_list_df_filtered$Group == "DOWN"]

# Combine the genes, first DOWN then UP (or vice versa based on preference)
ordered_genes_qc <- c(gene_list_df_filtered_up, gene_list_df_filtered_down)
library(RColorBrewer)
# Create DotPlot ordered
p1_group <- DotPlot(scRNAseqData, 
              features = ordered_genes_qc, 
              cols = "RdBu") + 
  theme(axis.text.x = element_text(angle = 45, hjust=1, size = 8)) +
  theme(axis.title.x = element_blank(), axis.title.y = element_blank()) # remove the y- and x-axis labels

p1_group

# Save the plots
ggsave(paste0(PLOT_loc, "/", Today, ".DotPlot.Targets.Grouped.png"), plot = p1_group)
Saving 7.29 x 4.51 in image
ggsave(paste0(PLOT_loc, "/", Today, ".DotPlot.Targets.Grouped.ps"), plot = p1_group)
Saving 7.29 x 4.51 in image
ggsave(paste0(PLOT_loc, "/", Today, ".DotPlot.Targets.Grouped.pdf"), plot = p1_group)
Saving 7.29 x 4.51 in image

Plotting gender

We should also plot these data stratified by gender smooth muscle cells.

Create subsets
unique(scRNAseqDataCEA39$Gender)
[1] male   female
Levels: female male
# Subset Seurat object for Diabetic Patients
male_cells <- WhichCells(scRNAseqDataCEA39, expression = Gender == "male")
scRNAseqDataCEA39_males <- subset(scRNAseqDataCEA39, cells = male_cells)

# Subset Seurat object for Non-Diabetic Patients
female_cells <- WhichCells(scRNAseqDataCEA39, expression = Gender == "female")
scRNAseqDataCEA39_females <- subset(scRNAseqDataCEA39, cells = female_cells)
Smooth muscle cells
# Define the cell identities you want to include in the plot
selected_idents_sma <- c("ACTA2+ SMC")
library(RColorBrewer)
library(cowplot)  # For combining plots

Attaching package: ‘cowplot’

The following object is masked from ‘package:patchwork’:

    align_plots

The following objects are masked from ‘package:sjPlot’:

    plot_grid, save_plot

The following object is masked from ‘package:ggpubr’:

    get_legend

The following object is masked from ‘package:lubridate’:

    stamp
# Create DotPlot for males
p1_males_sma <- DotPlot(scRNAseqDataCEA39_males,
                       features = ordered_genes_qc,
                       idents = selected_idents_sma, 
                       
                       cols = "RdBu") + 
  theme(axis.text.x = element_text(angle = 45, hjust = 1, size = 8)) +
  theme(axis.title.x = element_blank(), axis.title.y = element_blank()) + 
  ggtitle("Males")
Warning: Only one identity present, the expression values will be not scaled
# Create DotPlot for females
p2_females_sma <- DotPlot(scRNAseqDataCEA39_females,
                           features = ordered_genes_qc,
                           idents = selected_idents_sma,
                           
                           cols = "RdBu") + 
  theme(axis.text.x = element_text(angle = 45, hjust = 1, size = 8)) +
  theme(axis.title.x = element_blank(), axis.title.y = element_blank()) + 
  # theme(axis.title.x = element_blank(),
  #       axis.title.y = element_blank(),
  #       axis.text.y = element_blank(),  # Remove y-axis text
  #       axis.ticks.y = element_blank()) +  # Remove y-axis ticks 
  ggtitle("Females")
Warning: Only one identity present, the expression values will be not scaled
# Combine the two plots into one panel using cowplot
combined_plot_sma <- plot_grid(p1_males_sma, p2_females_sma, ncol = 2)

# Display the combined plot
print(combined_plot_sma)


# Save the plots
ggsave(paste0(PLOT_loc, "/", Today, ".DotPlot.Targets.ColocGrouped.SMAonly.GenderMales.png"), plot = p1_males_sma)
Saving 7.29 x 4.51 in image
ggsave(paste0(PLOT_loc, "/", Today, ".DotPlot.Targets.ColocGrouped.SMAonly.GenderMales.ps"), plot = p1_males_sma)
Saving 7.29 x 4.51 in image
ggsave(paste0(PLOT_loc, "/", Today, ".DotPlot.Targets.ColocGrouped.SMAonly.GenderMales.pdf"), plot = p1_males_sma)
Saving 7.29 x 4.51 in image
ggsave(paste0(PLOT_loc, "/", Today, ".DotPlot.Targets.ColocGrouped.SMAonly.GenderFemales.png"), plot = p2_females_sma)
Saving 7.29 x 4.51 in image
ggsave(paste0(PLOT_loc, "/", Today, ".DotPlot.Targets.ColocGrouped.SMAonly.GenderFemales.ps"), plot = p2_females_sma)
Saving 7.29 x 4.51 in image
ggsave(paste0(PLOT_loc, "/", Today, ".DotPlot.Targets.ColocGrouped.SMAonly.GenderFemales.pdf"), plot = p2_females_sma)
Saving 7.29 x 4.51 in image
ggsave(paste0(PLOT_loc, "/", Today, ".DotPlot.Targets.ColocGrouped.SMAonly.Gender.png"), plot = combined_plot_sma)
Saving 7.29 x 4.51 in image
ggsave(paste0(PLOT_loc, "/", Today, ".DotPlot.Targets.ColocGrouped.SMAonly.Gender.ps"), plot = combined_plot_sma)
Saving 7.29 x 4.51 in image
ggsave(paste0(PLOT_loc, "/", Today, ".DotPlot.Targets.ColocGrouped.SMAonly.Gender.pdf"), plot = combined_plot_sma)
Saving 7.29 x 4.51 in image

FeaturePlot(scRNAseqDataCEA39, features = c(target_genes_qc),
            cols =  c("#ECECEC", "#DB003F", "#9A3480","#1290D9"),
            combine = TRUE)

ggsave(paste0(PLOT_loc, "/", Today, ".FeaturePlot.Targets.png"), plot = last_plot())
ggsave(paste0(PLOT_loc, "/", Today, ".FeaturePlot.Targets.ps"), plot = last_plot())

# VlnPlot(scRNAseqDataCEA39, features = "DUSP27")

# VlnPlot files
ifelse(!dir.exists(file.path(PLOT_loc, "/VlnPlot")), 
       dir.create(file.path(PLOT_loc, "/VlnPlot")), 
       FALSE)
[1] TRUE
VlnPlot_loc = paste0(PLOT_loc, "/VlnPlot")


for (GENE in target_genes_qc){
  print(paste0("Projecting the expression of ", GENE, "."))

  vp1 <-  VlnPlot(scRNAseqDataCEA39, features = GENE) + 
    xlab("cell communities") + 
    ylab(bquote("normalized expression")) +
    theme(axis.title.x = element_text(color = "#000000", size = 14, face = "bold"), 
            axis.title.y = element_text(color = "#000000", size = 14, face = "bold"), 
            legend.position = "none")
    ggsave(paste0(VlnPlot_loc, "/", Today, ".VlnPlot.",GENE,".png"), plot = last_plot())
    ggsave(paste0(VlnPlot_loc, "/", Today, ".VlnPlot.",GENE,".ps"), plot = last_plot())
    ggsave(paste0(VlnPlot_loc, "/", Today, ".VlnPlot.",GENE,".pdf"), plot = last_plot())
  
  # print(vp1)
  
}
[1] "Projecting the expression of ADAP1."
Saving 7 x 7 in image
[1] "Projecting the expression of BAHD1."
[1] "Projecting the expression of CHAF1A."
[1] "Projecting the expression of DISP2."
[1] "Projecting the expression of FAM98B."
[1] "Projecting the expression of GNA11."
[1] "Projecting the expression of GPR176."
[1] "Projecting the expression of KNL1."
[1] "Projecting the expression of MDFIC."
[1] "Projecting the expression of MPND."
[1] "Projecting the expression of NDUFA11."
[1] "Projecting the expression of PIP5K1C."
[1] "Projecting the expression of SUN1."
[1] "Projecting the expression of TLE5."
[1] "Projecting the expression of ZFAND2A."

Differential expression between cell communities

Here we project genes to only the broad cell communities:

  • macrophages
  • endothelial cells
  • smooth muscle cells
  • T-cells
  • B-cells
  • Mast cells
  • NK-cells
  • Mixed cells

Macrophages

unique(scRNAseqDataCEA39@active.ident)
 [1] CD3+ TC I                  CD3+ TC IV                 CD34+ EC I                 CD3+ TC V                 
 [5] CD3+CD56+ NK II            CD3+ TC VI                 CD68+IL18+TLR4+TREM2+ MRes CD3+CD56+ NK I            
 [9] ACTA2+ SMC                 CD3+ TC II                 FOXP3+ TC                  CD34+ EC II               
[13] CD3+ TC III                CD68+CD1C+ DC              CD68+CASP1+IL1B+SELL MInf  CD79A+ BCmem              
[17] CD68+ABCA1+OLR1+TREM2+ FC  CD68+KIT+ MC               CD68+CD4+ Mono             CD79+ BCplasma            
20 Levels: CD68+CD4+ Mono CD68+IL18+TLR4+TREM2+ MRes CD68+CD1C+ DC CD68+CASP1+IL1B+SELL MInf ... CD79+ BCplasma

Comparison between the macrophages cell communities (CD14/CD68+), and all other communities.


MAC.markers <- FindMarkers(object = scRNAseqDataCEA39, 
                          ident.1 = c("CD68+CASP1+IL1B+SELL MInf", 
                                      "CD68+CD1C+ DC", 
                                      "CD68+CD4+ Mono",
                                      "CD68+IL18+TLR4+TREM2+ MRes",
                                      "CD68+ABCA1+OLR1+TREM2+ FC"), 
                          ident.2 = c(#"CD68+CASP1+IL1B+SELL MInf", 
                                      #"CD68+CD1C+ DC", 
                                      #"CD68+CD4+ Mono",
                                      #"CD68+IL18+TLR4+TREM2+ MRes",
                                      #"CD68+ABCA1+OLR1+TREM2+ FC",
                                      "CD3+ TC I",
                                      "CD3+ TC II", 
                                      "CD3+ TC III", 
                                      "CD3+ TC IV", 
                                      "CD3+ TC V", 
                                      "CD3+ TC VI", 
                                      "FOXP3+ TC", 
                                      "CD34+ EC I", 
                                      "CD34+ EC II",
                                      "ACTA2+ SMC", 
                                      "CD3+CD56+ NK I",
                                      "CD3+CD56+ NK II", 
                                      "CD68+KIT+ MC",
                                      "CD79+ BCplasma", 
                                      "CD79A+ BCmem"))

DT::datatable(MAC.markers)
Warning: It seems your data is too big for client-side DataTables. You may consider server-side processing: https://rstudio.github.io/DT/server.htmlWarning: It seems your data is too big for client-side DataTables. You may consider server-side processing: https://rstudio.github.io/DT/server.html
MAC_Volcano_TargetsA = EnhancedVolcano(MAC.markers,
    lab = rownames(MAC.markers),
    x = "avg_log2FC",
    y = "p_val_adj",
    selectLab = target_genes_qc,
    axisLabSize = 12,
    xlab = "average fold-change",
    title = "Macrophage markers\n(Macrophage communities vs the rest)",
    titleLabSize = 14,
    pCutoff = 0.05/(nrow(MAC.markers)), # 20552 genes
    FCcutoff = 1.25,
    pointSize = 1.5,
    labSize = 3.0,
    legendLabels =c('NS','avg. fold-change','P',
      'P & avg. fold-change'),
    legendPosition = "right",
    legendLabSize = 10,
    legendIconSize = 3.0,
    drawConnectors = TRUE,
    widthConnectors = 0.2,
    colConnectors = "#595A5C",
    gridlines.major = FALSE,
    gridlines.minor = FALSE)
MAC_Volcano_TargetsA
ggsave(paste0(PLOT_loc, "/", Today, ".Volcano.MAC.DEG.Targets.pdf"), 
       plot = MAC_Volcano_TargetsA)

The target results are given below and written to a file.

library(tibble)
MAC.markers <- add_column(MAC.markers, Gene = row.names(MAC.markers), .before = 1)

temp <- MAC.markers[MAC.markers$Gene %in% target_genes_qc,]

DT::datatable(temp)
fwrite(temp, file = paste0(OUT_loc, "/", Today, ".MAC.DEG.Targets.txt"),
       quote = FALSE,
       sep = "\t", 
       showProgress = FALSE, verbose = FALSE)

Smooth muscle cells

Comparison between the smooth muscle cell communities (ACTA2+), and all other communities.


SMC.markers <- FindMarkers(object = scRNAseqDataCEA39, 
                          ident.1 = c("ACTA2+ SMC"), 
                          ident.2 = c("CD68+CASP1+IL1B+SELL MInf", 
                                      "CD68+CD1C+ DC", 
                                      "CD68+CD4+ Mono",
                                      "CD68+IL18+TLR4+TREM2+ MRes",
                                      "CD68+ABCA1+OLR1+TREM2+ FC",
                                      "CD3+ TC I",
                                      "CD3+ TC II", 
                                      "CD3+ TC III", 
                                      "CD3+ TC IV", 
                                      "CD3+ TC V", 
                                      "CD3+ TC VI", 
                                      "FOXP3+ TC", 
                                      "CD34+ EC I", 
                                      "CD34+ EC II",
                                      #"ACTA2+ SMC", 
                                      "CD3+CD56+ NK I",
                                      "CD3+CD56+ NK II", 
                                      "CD68+KIT+ MC",
                                      "CD79+ BCplasma", 
                                      "CD79A+ BCmem"))

DT::datatable(SMC.markers)
Warning: It seems your data is too big for client-side DataTables. You may consider server-side processing: https://rstudio.github.io/DT/server.htmlWarning: It seems your data is too big for client-side DataTables. You may consider server-side processing: https://rstudio.github.io/DT/server.html
SMC_Volcano_TargetsA = EnhancedVolcano(SMC.markers,
    lab = rownames(SMC.markers),
    x = "avg_log2FC",
    y = "p_val_adj",
    selectLab = target_genes_qc,
    axisLabSize = 12,
    xlab = "average fold-change",
    title = "SMC markers\n(SMC communities vs the rest)",
    titleLabSize = 14,
    pCutoff = 0.05/(nrow(SMC.markers)), # 20552 genes
    FCcutoff = 1.25,
    pointSize = 1.5,
    labSize = 3.0,
    legendLabels =c('NS','avg. fold-change','P',
      'P & avg. fold-change'),
    legendPosition = "right",
    legendLabSize = 10,
    legendIconSize = 3.0,
    drawConnectors = TRUE,
    widthConnectors = 0.2,
    colConnectors = "#595A5C",
    gridlines.major = FALSE,
    gridlines.minor = FALSE)
SMC_Volcano_TargetsA
ggsave(paste0(PLOT_loc, "/", Today, ".Volcano.SMC.DEG.Targets.pdf"), 
       plot = SMC_Volcano_TargetsA)

The target results are given below and written to a file.

library(tibble)
SMC.markers <- add_column(SMC.markers, Gene = row.names(SMC.markers), .before = 1)

temp <- SMC.markers[SMC.markers$Gene %in% target_genes_qc,]

DT::datatable(temp)
fwrite(temp, file = paste0(OUT_loc, "/", Today, ".SMC.DEG.Targets.txt"),
       quote = FALSE,
       sep = "\t", 
       showProgress = FALSE, verbose = FALSE)

Endothelial cells

Comparison between the endothelial cell communities (CD34+), and all other communities.


EC.markers <- FindMarkers(object = scRNAseqDataCEA39, 
                          ident.1 = c("CD34+ EC I", 
                                      "CD34+ EC II"), 
                          ident.2 = c("CD68+CASP1+IL1B+SELL MInf", 
                                      "CD68+CD1C+ DC", 
                                      "CD68+CD4+ Mono",
                                      "CD68+IL18+TLR4+TREM2+ MRes",
                                      "CD68+ABCA1+OLR1+TREM2+ FC",
                                      "CD3+ TC I",
                                      "CD3+ TC II", 
                                      "CD3+ TC III", 
                                      "CD3+ TC IV", 
                                      "CD3+ TC V", 
                                      "CD3+ TC VI", 
                                      "FOXP3+ TC", 
                                      # "CD34+ EC I", 
                                      # "CD34+ EC II",
                                      "ACTA2+ SMC", 
                                      "CD3+CD56+ NK I",
                                      "CD3+CD56+ NK II", 
                                      "CD68+KIT+ MC",
                                      "CD79+ BCplasma", 
                                      "CD79A+ BCmem"))

DT::datatable(EC.markers)
Warning: It seems your data is too big for client-side DataTables. You may consider server-side processing: https://rstudio.github.io/DT/server.htmlWarning: It seems your data is too big for client-side DataTables. You may consider server-side processing: https://rstudio.github.io/DT/server.html
EC_Volcano_TargetsA = EnhancedVolcano(EC.markers,
    lab = rownames(EC.markers),
    x = "avg_log2FC",
    y = "p_val_adj",
    selectLab = target_genes_qc,
    axisLabSize = 12,
    xlab = "average fold-change",
    title = "Endothelial cell markers\n(EC communities vs the rest)",
    titleLabSize = 14,
    pCutoff = 0.05/(nrow(EC.markers)), # 20552 genes
    FCcutoff = 1.25,
    pointSize = 1.5,
    labSize = 3.0,
    legendLabels =c('NS','avg. fold-change','P',
      'P & avg. fold-change'),
    legendPosition = "right",
    legendLabSize = 10,
    legendIconSize = 3.0,
    drawConnectors = TRUE,
    widthConnectors = 0.2,
    colConnectors = "#595A5C",
    gridlines.major = FALSE,
    gridlines.minor = FALSE)
EC_Volcano_TargetsA
ggsave(paste0(PLOT_loc, "/", Today, ".Volcano.EC.DEG.Targets.pdf"), 
       plot = EC_Volcano_TargetsA)

The target results are given below and written to a file.

library(tibble)
EC.markers <- add_column(EC.markers, Gene = row.names(EC.markers), .before = 1)

temp <- EC.markers[EC.markers$Gene %in% target_genes_qc,]

DT::datatable(temp)
fwrite(temp, file = paste0(OUT_loc, "/", Today, ".EC.DEG.Targets.txt"),
       quote = FALSE,
       sep = "\t", 
       showProgress = FALSE, verbose = FALSE)

T-cells

Comparison between the T-cell communities (CD3/CD4/CD8+), and all other communities.


TC.markers <- FindMarkers(object = scRNAseqDataCEA39, 
                          ident.1 = c("CD3+ TC I",
                                      "CD3+ TC II", 
                                      "CD3+ TC III", 
                                      "CD3+ TC IV", 
                                      "CD3+ TC V", 
                                      "CD3+ TC VI", 
                                      "FOXP3+ TC"), 
                          ident.2 = c("CD68+CASP1+IL1B+SELL MInf", 
                                      "CD68+CD1C+ DC", 
                                      "CD68+CD4+ Mono",
                                      "CD68+IL18+TLR4+TREM2+ MRes",
                                      "CD68+ABCA1+OLR1+TREM2+ FC",
                                      # "CD3+ TC I",
                                      # "CD3+ TC II", 
                                      # "CD3+ TC III", 
                                      # "CD3+ TC IV", 
                                      # "CD3+ TC V", 
                                      # "CD3+ TC VI", 
                                      # "FOXP3+ TC", 
                                      "CD34+ EC I", 
                                      "CD34+ EC II",
                                      "ACTA2+ SMC", 
                                      "CD3+CD56+ NK I",
                                      "CD3+CD56+ NK II", 
                                      "CD68+KIT+ MC",
                                      "CD79+ BCplasma", 
                                      "CD79A+ BCmem"))

DT::datatable(TC.markers)
Warning: It seems your data is too big for client-side DataTables. You may consider server-side processing: https://rstudio.github.io/DT/server.htmlWarning: It seems your data is too big for client-side DataTables. You may consider server-side processing: https://rstudio.github.io/DT/server.html
TC_Volcano_TargetsA = EnhancedVolcano(TC.markers,
    lab = rownames(TC.markers),
    x = "avg_log2FC",
    y = "p_val_adj",
    selectLab = target_genes_qc,
    axisLabSize = 12,
    xlab = "average fold-change",
    title = "T-cell markers\n(T-cell communities vs the rest)",
    titleLabSize = 14,
    pCutoff = 0.05/nrow(TC.markers), # 20552 genes
    FCcutoff = 1.25,
    pointSize = 1.5,
    labSize = 3.0,
    legendLabels =c('NS','avg. fold-change','P',
      'P & avg. fold-change'),
    legendPosition = "right",
    legendLabSize = 10,
    legendIconSize = 3.0,
    drawConnectors = TRUE,
    widthConnectors = 0.2,
    colConnectors = "#595A5C",
    gridlines.major = FALSE,
    gridlines.minor = FALSE)
TC_Volcano_TargetsA
ggsave(paste0(PLOT_loc, "/", Today, ".Volcano.TC.DEG.Targets.pdf"), 
       plot = TC_Volcano_TargetsA)

The target results are given below and written to a file.

library(tibble)
TC.markers <- add_column(TC.markers, Gene = row.names(TC.markers), .before = 1)

temp <- TC.markers[TC.markers$Gene %in% target_genes_qc,]

DT::datatable(temp)
fwrite(temp, file = paste0(OUT_loc, "/", Today, ".TC.DEG.Targets.txt"),
       quote = FALSE,
       sep = "\t", 
       showProgress = FALSE, verbose = FALSE)

B-cells

Comparison between the B-cell communities (CD79A+), and all other communities.


BC.markers <- FindMarkers(object = scRNAseqDataCEA39, 
                          ident.1 = c("CD79+ BCplasma", 
                                      "CD79A+ BCmem"), 
                          ident.2 = c("CD68+CASP1+IL1B+SELL MInf", 
                                      "CD68+CD1C+ DC", 
                                      "CD68+CD4+ Mono",
                                      "CD68+IL18+TLR4+TREM2+ MRes",
                                      "CD68+ABCA1+OLR1+TREM2+ FC",
                                      "CD3+ TC I",
                                      "CD3+ TC II", 
                                      "CD3+ TC III", 
                                      "CD3+ TC IV", 
                                      "CD3+ TC V", 
                                      "CD3+ TC VI", 
                                      "FOXP3+ TC", 
                                      "CD34+ EC I", 
                                      "CD34+ EC II",
                                      "ACTA2+ SMC", 
                                      "CD3+CD56+ NK I",
                                      "CD3+CD56+ NK II", 
                                      "CD68+KIT+ MC"
                                      # "CD79+ BCplasma", 
                                      # "CD79A+ BCmem"
                                      ))

DT::datatable(BC.markers)
Warning: It seems your data is too big for client-side DataTables. You may consider server-side processing: https://rstudio.github.io/DT/server.htmlWarning: It seems your data is too big for client-side DataTables. You may consider server-side processing: https://rstudio.github.io/DT/server.html
BC_Volcano_TargetsA = EnhancedVolcano(BC.markers,
    lab = rownames(BC.markers),
    x = "avg_log2FC",
    y = "p_val_adj",
    selectLab = target_genes_qc,
    axisLabSize = 12,
    xlab = "average fold-change",
    title = "B-cell markers\n(B-cell communities vs the rest)",
    titleLabSize = 14,
    pCutoff = 0.05/nrow(BC.markers), # 20552 genes
    FCcutoff = 1.25,
    pointSize = 1.5,
    labSize = 3.0,
    legendLabels =c('NS','avg. fold-change','P',
      'P & avg. fold-change'),
    legendPosition = "right",
    legendLabSize = 10,
    legendIconSize = 3.0,
    drawConnectors = TRUE,
    widthConnectors = 0.2,
    colConnectors = "#595A5C",
    gridlines.major = FALSE,
    gridlines.minor = FALSE)
BC_Volcano_TargetsA
ggsave(paste0(PLOT_loc, "/", Today, ".Volcano.BC.DEG.Targets.pdf"), 
       plot = BC_Volcano_TargetsA)

The target results are given below and written to a file.

library(tibble)
BC.markers <- add_column(BC.markers, Gene = row.names(BC.markers), .before = 1)

temp <- BC.markers[BC.markers$Gene %in% target_genes_qc,]

DT::datatable(temp)
fwrite(temp, file = paste0(OUT_loc, "/", Today, ".BC.DEG.Targets.txt"),
       quote = FALSE,
       sep = "\t", 
       showProgress = FALSE, verbose = FALSE)

Mast cells

Comparison between the mast cell communities (KIT+), and all other communities.


MC.markers <- FindMarkers(object = scRNAseqDataCEA39, 
                          ident.1 = c("CD68+KIT+ MC"), 
                          ident.2 = c("CD68+CASP1+IL1B+SELL MInf", 
                                      "CD68+CD1C+ DC", 
                                      "CD68+CD4+ Mono",
                                      "CD68+IL18+TLR4+TREM2+ MRes",
                                      "CD68+ABCA1+OLR1+TREM2+ FC",
                                      "CD3+ TC I",
                                      "CD3+ TC II", 
                                      "CD3+ TC III", 
                                      "CD3+ TC IV", 
                                      "CD3+ TC V", 
                                      "CD3+ TC VI", 
                                      "FOXP3+ TC", 
                                      "CD34+ EC I", 
                                      "CD34+ EC II",
                                      "ACTA2+ SMC", 
                                      "CD3+CD56+ NK I",
                                      "CD3+CD56+ NK II", 
                                      # "CD68+KIT+ MC",
                                      "CD79+ BCplasma", 
                                      "CD79A+ BCmem"))

DT::datatable(MC.markers)
Warning: It seems your data is too big for client-side DataTables. You may consider server-side processing: https://rstudio.github.io/DT/server.htmlWarning: It seems your data is too big for client-side DataTables. You may consider server-side processing: https://rstudio.github.io/DT/server.html
MC_Volcano_TargetsA = EnhancedVolcano(MC.markers,
    lab = rownames(MC.markers),
    x = "avg_log2FC",
    y = "p_val_adj",
    selectLab = target_genes_qc,
    axisLabSize = 12,
    xlab = "average fold-change",
    title = "Mast cell markers\n(Mast cell communities vs the rest)",
    titleLabSize = 14,
    pCutoff = 0.05/nrow(MC.markers), # 20552 genes
    FCcutoff = 1.25,
    pointSize = 1.5,
    labSize = 3.0,
    legendLabels =c('NS','avg. fold-change','P',
      'P & avg. fold-change'),
    legendPosition = "right",
    legendLabSize = 10,
    legendIconSize = 3.0,
    drawConnectors = TRUE,
    widthConnectors = 0.2,
    colConnectors = "#595A5C",
    gridlines.major = FALSE,
    gridlines.minor = FALSE)
MC_Volcano_TargetsA
ggsave(paste0(PLOT_loc, "/", Today, ".Volcano.MC.DEG.Targets.pdf"), 
       plot = MC_Volcano_TargetsA)

The target results are given below and written to a file.

library(tibble)
MC.markers <- add_column(MC.markers, Gene = row.names(MC.markers), .before = 1)

temp <- MC.markers[MC.markers$Gene %in% target_genes_qc,]

DT::datatable(temp)
fwrite(temp, file = paste0(OUT_loc, "/", Today, ".MC.DEG.Targets.txt"),
       quote = FALSE,
       sep = "\t", 
       showProgress = FALSE, verbose = FALSE)

NK-cells

Comparison between the natural killer cell communities (NCAM1+), and all other communities.


NK.markers <- FindMarkers(object = scRNAseqDataCEA39, 
                          ident.1 = c("CD3+CD56+ NK I",
                                      "CD3+CD56+ NK II"), 
                          ident.2 = c("CD68+CASP1+IL1B+SELL MInf", 
                                      "CD68+CD1C+ DC", 
                                      "CD68+CD4+ Mono",
                                      "CD68+IL18+TLR4+TREM2+ MRes",
                                      "CD68+ABCA1+OLR1+TREM2+ FC",
                                      "CD3+ TC I",
                                      "CD3+ TC II", 
                                      "CD3+ TC III", 
                                      "CD3+ TC IV", 
                                      "CD3+ TC V", 
                                      "CD3+ TC VI", 
                                      "FOXP3+ TC", 
                                      "CD34+ EC I", 
                                      "CD34+ EC II",
                                      "ACTA2+ SMC", 
                                      # "CD3+CD56+ NK I",
                                      # "CD3+CD56+ NK II", 
                                      "CD68+KIT+ MC",
                                      "CD79+ BCplasma", 
                                      "CD79A+ BCmem"))

DT::datatable(NK.markers)
Warning: It seems your data is too big for client-side DataTables. You may consider server-side processing: https://rstudio.github.io/DT/server.htmlWarning: It seems your data is too big for client-side DataTables. You may consider server-side processing: https://rstudio.github.io/DT/server.html
NK_Volcano_TargetsA = EnhancedVolcano(NK.markers,
    lab = rownames(NK.markers),
    x = "avg_log2FC",
    y = "p_val_adj",
    selectLab = target_genes_qc,
    axisLabSize = 12,
    xlab = "average fold-change",
    title = "NK markers\n(NK-cell communities vs the rest)",
    titleLabSize = 14,
    pCutoff = 0.05/nrow(NK.markers), # 20552 genes
    FCcutoff = 1.25,
    pointSize = 1.5,
    labSize = 3.0,
    legendLabels =c('NS','avg. fold-change','P',
      'P & avg. fold-change'),
    legendPosition = "right",
    legendLabSize = 10,
    legendIconSize = 3.0,
    drawConnectors = TRUE,
    widthConnectors = 0.2,
    colConnectors = "#595A5C",
    gridlines.major = FALSE,
    gridlines.minor = FALSE)
NK_Volcano_TargetsA
ggsave(paste0(PLOT_loc, "/", Today, ".Volcano.NK.DEG.Targets.pdf"), 
       plot = NK_Volcano_TargetsA)

The target results are given below and written to a file.

library(tibble)
NK.markers <- add_column(NK.markers, Gene = row.names(NK.markers), .before = 1)

temp <- NK.markers[NK.markers$Gene %in% target_genes_qc,]

DT::datatable(temp)
fwrite(temp, file = paste0(OUT_loc, "/", Today, ".NK.DEG.Targets.txt"),
       quote = FALSE,
       sep = "\t", 
       showProgress = FALSE, verbose = FALSE)

Session information


Version:      v1.2.0
Last update:  2024-10-17
Written by:   Sander W. van der Laan (s.w.vanderlaan-2[at]umcutrecht.nl).
Description:  Script to load single-cell RNA sequencing (scRNAseq) data, and perform quality control (QC), and initial mapping to cells.
Minimum requirements: R version 3.5.2 (2018-12-20) -- 'Eggshell Igloo', macOS Mojave (10.14.2).

**MoSCoW To-Do List**
The things we Must, Should, Could, and Would have given the time we have.
_M_

_S_

_C_

_W_

**Changes log**
* v1.2.0 Fixed an issue where the subset of scRNAseq was loosing cell-identities.
* v1.1.1 Textual fixes.
* v1.1.1 Fix writing baseline table.
* v1.1.0 Update to study database.
* v1.0.2 Fixes to the start of the notebook. Update to loading of the clinical data. Fix on the gene-filtering.
* v1.0.1 Update to main AEDB (there is an error in the Age-variable in the new version). Fewer patients in scRNAseq (32 vs 39 with the newer dataset).
* v1.0.0 Initial version.

sessionInfo()
R version 4.4.1 (2024-06-14)
Platform: x86_64-apple-darwin20
Running under: macOS 15.1

Matrix products: default
BLAS:   /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib 
LAPACK: /Library/Frameworks/R.framework/Versions/4.4-x86_64/Resources/lib/libRlapack.dylib;  LAPACK version 3.12.0

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

time zone: America/New_York
tzcode source: internal

attached base packages:
 [1] stats4    grid      tools     stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] cowplot_1.1.3          RColorBrewer_1.1-3     rmarkdown_2.28         Seurat_5.1.0           SeuratObject_5.0.2    
 [6] sp_2.1-4               BiocManager_1.30.25    EnhancedVolcano_1.22.0 ggrepel_0.9.6          mygene_1.40.0         
[11] txdbmaker_1.0.1        GenomicFeatures_1.56.0 GenomicRanges_1.56.2   GenomeInfoDb_1.40.1    org.Hs.eg.db_3.19.1   
[16] AnnotationDbi_1.66.0   IRanges_2.38.1         S4Vectors_0.42.1       Biobase_2.64.0         BiocGenerics_0.50.0   
[21] tidylog_1.1.0          patchwork_1.3.0.9000   labelled_2.13.0        sjPlot_2.8.16          UpSetR_1.4.0          
[26] ggpubr_0.6.0.999       forestplot_3.1.5       abind_1.4-8            checkmate_2.3.2        pheatmap_1.0.12       
[31] devtools_2.4.5         usethis_3.0.0          BlandAltmanLeh_0.3.1   tableone_0.13.2        openxlsx_4.2.7.1      
[36] haven_2.5.4            eeptools_1.2.5         DT_0.33                knitr_1.48             lubridate_1.9.3       
[41] forcats_1.0.0          stringr_1.5.1          purrr_1.0.2            tibble_3.2.1           ggplot2_3.5.1         
[46] tidyverse_2.0.0        data.table_1.16.2      naniar_1.1.0           tidyr_1.3.1            dplyr_1.1.4           
[51] optparse_1.7.5         readr_2.1.5            pander_0.6.5           R.utils_2.12.3         R.oo_1.26.0           
[56] R.methodsS3_1.8.2      worcs_0.1.15           credentials_2.0.2     

loaded via a namespace (and not attached):
  [1] sjmisc_2.8.10               progress_1.2.3              urlchecker_1.0.1            nnet_7.3-19                
  [5] goftest_1.2-3               Biostrings_2.72.1           vctrs_0.6.5                 spatstat.random_3.3-2      
  [9] rticles_0.27                digest_0.6.37               png_0.1-8                   proxy_0.4-27               
 [13] deldir_2.0-4                parallelly_1.38.0           renv_1.0.11                 MASS_7.3-61                
 [17] reshape2_1.4.4              httpuv_1.6.15               withr_3.0.1                 ggrastr_1.0.2              
 [21] xfun_0.48                   ellipsis_0.3.2              survival_3.7-0              memoise_2.0.1              
 [25] ggbeeswarm_0.7.2            profvis_0.4.0               systemfonts_1.1.0           ragg_1.3.3                 
 [29] zoo_1.8-12                  pbapply_1.7-2               Formula_1.2-5               sys_3.4.3                  
 [33] prettyunits_1.2.0           datawizard_0.13.0           KEGGREST_1.44.1             promises_1.3.0             
 [37] httr_1.4.7                  rstatix_0.7.2               restfulr_0.0.15             globals_0.16.3             
 [41] fitdistrplus_1.2-1          rstudioapi_0.16.0           UCSC.utils_1.0.0            miniUI_0.1.1.1             
 [45] generics_0.1.3              base64enc_0.1-3             curl_5.2.3                  mitools_2.4                
 [49] zlibbioc_1.50.0             polyclip_1.10-7             ggeffects_1.7.2             GenomeInfoDbData_1.2.12    
 [53] SparseArray_1.4.8           xtable_1.8-4                evaluate_1.0.1              S4Arrays_1.4.1             
 [57] BiocFileCache_2.12.0        hms_1.1.3                   irlba_2.3.5.1               colorspace_2.1-1           
 [61] filelock_1.0.3              getopt_1.20.4               ROCR_1.0-11                 spatstat.data_3.1-2        
 [65] reticulate_1.39.0           magrittr_2.0.3              lmtest_0.9-40               later_1.3.2                
 [69] lattice_0.22-6              spatstat.geom_3.3-3         future.apply_1.11.2         scattermore_1.2            
 [73] XML_3.99-0.17               survey_4.4-2                matrixStats_1.4.1           RcppAnnoy_0.0.22           
 [77] class_7.3-22                Hmisc_5.1-3                 pillar_1.9.0                nlme_3.1-166               
 [81] performance_0.12.3          compiler_4.4.1              RSpectra_0.16-2             stringi_1.8.4              
 [85] tensor_1.5                  minqa_1.2.8                 SummarizedExperiment_1.34.0 GenomicAlignments_1.40.0   
 [89] plyr_1.8.9                  crayon_1.5.3                BiocIO_1.14.0               chron_2.3-61               
 [93] bit_4.5.0                   textshaping_0.4.0           codetools_0.2-20            clisymbols_1.2.0           
 [97] openssl_2.2.2               crosstalk_1.2.1             bslib_0.8.0                 e1071_1.7-16               
[101] plotly_4.10.4               mime_0.12                   splines_4.4.1               Rcpp_1.0.13                
[105] fastDummies_1.7.4           dbplyr_2.5.0                blob_1.2.4                  utf8_1.2.4                 
[109] lme4_1.1-35.5               fs_1.6.4                    listenv_0.9.1               prereg_0.6.0               
[113] pkgbuild_1.4.4              gh_1.4.1                    ggsignif_0.6.4              sqldf_0.4-11               
[117] Matrix_1.7-0                statmod_1.5.0               tzdb_0.4.0                  visdat_0.6.0               
[121] pkgconfig_2.0.3             cachem_1.1.0                RSQLite_2.3.7               viridisLite_0.4.2          
[125] DBI_1.2.3                   fastmap_1.2.0               scales_1.3.0                ica_1.0-3                  
[129] Rsamtools_2.20.0            broom_1.0.7                 sass_0.4.9                  coda_0.19-4.1              
[133] insight_0.20.5              dotCall64_1.2               carData_3.0-5               RANN_2.6.2                 
[137] rpart_4.1.23                farver_2.1.2                gsubfn_0.7                  yaml_2.3.10                
[141] MatrixGenerics_1.16.0       foreign_0.8-87              sjstats_0.19.0              rtracklayer_1.64.0         
[145] cli_3.6.3                   leiden_0.4.3.1              lifecycle_1.0.4             uwot_0.2.2                 
[149] askpass_1.2.1               presto_1.0.0                sessioninfo_1.2.2           backports_1.5.0            
[153] BiocParallel_1.38.0         timechange_0.3.0            gtable_0.3.5                rjson_0.2.23               
[157] ggridges_0.5.6              progressr_0.14.0            limma_3.60.6                parallel_4.4.1             
[161] jsonlite_1.8.9              RcppHNSW_0.6.0              bitops_1.0-9                bit64_4.5.2                
[165] Rtsne_0.17                  spatstat.utils_3.1-0        proto_1.0.0                 zip_2.3.1                  
[169] ranger_0.16.0               jquerylib_0.1.4             spatstat.univar_3.0-1       lazyeval_0.2.2             
[173] shiny_1.9.1                 htmltools_0.5.8.1           sctransform_0.4.1           rappdirs_0.3.3             
[177] sjlabelled_1.2.0            tinytex_0.53                glue_1.8.0                  spam_2.11-0                
[181] httr2_1.0.5                 XVector_0.44.0              RCurl_1.98-1.16             gridExtra_2.3              
[185] boot_1.3-31                 igraph_2.0.3                R6_2.5.1                    arm_1.14-4                 
[189] vcd_1.4-13                  labeling_0.4.3              cluster_2.1.6               pkgload_1.4.0              
[193] nloptr_2.1.1                vipor_0.4.7                 DelayedArray_0.30.1         tidyselect_1.2.1           
[197] htmlTable_2.4.3             xml2_1.3.6                  car_3.1-3                   future_1.34.0              
[201] munsell_0.5.1               KernSmooth_2.23-24          htmlwidgets_1.6.4           spatstat.sparse_3.1-0      
[205] biomaRt_2.60.1              rlang_1.1.4                 spatstat.explore_3.3-2      gert_2.1.4                 
[209] remotes_2.5.0               fansi_1.0.6                 beeswarm_0.4.0             

Saving environment

rm(backup.scRNAseqData)
rm(scRNAseqData, scRNAseqDataCEA39)

save.image(paste0(PROJECT_loc, "/",Today,".",PROJECTNAME,".AESCRNA.results.RData"))
© 1979-2024 Sander W. van der Laan | s.w.vanderlaan[at]gmail[dot]com | vanderlaanand.science.
LS0tCnRpdGxlOiAiTWFwcGluZyB0YXJnZXRzIHRvIHNpbmdsZSBjZWxscyBpbiBwbGFxdWVzLiIKc3VidGl0bGU6IEFjY29tcGFueWluZyAnTVJfQ1ZEX01ERCcKYXV0aG9yOiAnW1NhbmRlciBXLiB2YW4gZGVyIExhYW4sIFBoRF0oaHR0cHM6Ly92YW5kZXJsYWFuYW5kLnNjaWVuY2UpIHwgcy53LnZhbmRlcmxhYW5bYXRdZ21haWxbZG90XWNvbScKZGF0ZTogJ2ByIFN5cy5EYXRlKClgJwpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazogCiAgICBjYWNoZTogeWVzCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKICAgIGNvbGxhcHNlOiB5ZXMKICAgIGRmX3ByaW50OiBwYWdlZAogICAgZmlnLmFsaWduOiBjZW50ZXIKICAgIGZpZ19jYXB0aW9uOiB5ZXMKICAgIGZpZ19oZWlnaHQ6IDEwCiAgICBmaWdfcmV0aW5hOiAyCiAgICBmaWdfd2lkdGg6IDEyCiAgICB0aGVtZTogcGFwZXIKICAgIHRvYzogeWVzCiAgICB0b2NfZmxvYXQ6CiAgICAgIGNvbGxhcHNlZDogbm8KICAgICAgc21vb3RoX3Njcm9sbDogeWVzCiAgICBoaWdobGlnaHQ6IHRhbmdvCm1haW5mb250OiBIZWx2ZXRpY2EKZWRpdG9yX29wdGlvbnM6CiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQpiaWJsaW9ncmFwaHk6IHJlZmVyZW5jZXMuYmliCmtuaXQ6IHdvcmNzOjpjaXRlX2FsbAotLS0KCiMgR2VuZXJhbCBTZXR1cApgYGB7ciBlY2hvID0gRkFMU0V9CnJtKGxpc3QgPSBscygpKQpgYGAKCmBgYHtyIExvY2FsU3lzdGVtLCBlY2hvID0gRkFMU0V9CnNvdXJjZSgic2NyaXB0cy9sb2NhbC5zeXN0ZW0uUiIpCmBgYAoKYGBge3IgU291cmNlIGZ1bmN0aW9uc30Kc291cmNlKCJzY3JpcHRzL2Z1bmN0aW9ucy5SIikKYGBgCgpgYGB7ciBsb2FkaW5nX3BhY2thZ2VzLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpzb3VyY2UoInNjcmlwdHMvcGFjazAzLnBhY2thZ2VzLlIiKQpgYGAKCmBgYHtyIFNldHRpbmc6IENvbG9yc30KVG9kYXkgPSBmb3JtYXQoYXMuRGF0ZShhcy5QT1NJWGx0KFN5cy50aW1lKCkpKSwgIiVZJW0lZCIpClRvZGF5LlJlcG9ydCA9IGZvcm1hdChhcy5EYXRlKGFzLlBPU0lYbHQoU3lzLnRpbWUoKSkpLCAiJUEsICVCICVkLCAlWSIpCnNvdXJjZSgic2NyaXB0cy9jb2xvcnMuUiIpCmBgYAoKYGBge3Igc2V0dXBfbm90ZWJvb2ssIGluY2x1ZGU9RkFMU0V9CiMgV2UgcmVjb21tZW5kIHRoYXQgeW91IHByZXBhcmUgeW91ciByYXcgZGF0YSBmb3IgYW5hbHlzaXMgaW4gJ3ByZXBhcmVfZGF0YS5SJywKIyBhbmQgZW5kIHRoYXQgZmlsZSB3aXRoIGVpdGhlciBvcGVuX2RhdGEoeW91cmRhdGEpLCBvciBjbG9zZWRfZGF0YSh5b3VyZGF0YSkuCiMgVGhlbiwgdW5jb21tZW50IHRoZSBsaW5lIGJlbG93IHRvIGxvYWQgdGhlIG9yaWdpbmFsIG9yIHN5bnRoZXRpYyBkYXRhCiMgKHdoaWNoZXZlciBpcyBhdmFpbGFibGUpLCB0byBhbGxvdyBhbnlvbmUgdG8gcmVwcm9kdWNlIHlvdXIgY29kZToKIyBsb2FkX2RhdGEoKQoKIyBmdXJ0aGVyIGRlZmluZSBzb21lIGtuaXRyLW9wdGlvbnMuCmtuaXRyOjpvcHRzX2NodW5rJHNldChmaWcud2lkdGggPSAxMiwgZmlnLmhlaWdodCA9IDgsIGZpZy5wYXRoID0gJ0ZpZ3VyZXMvJywgCiAgICAgICAgICAgICAgICAgICAgICB3YXJuaW5nID0gVFJVRSwgIyBzaG93IHdhcm5pbmdzIGR1cmluZyBjb2RlYm9vayBnZW5lcmF0aW9uCiAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gVFJVRSwgIyBzaG93IG1lc3NhZ2VzIGR1cmluZyBjb2RlYm9vayBnZW5lcmF0aW9uCiAgICAgICAgICAgICAgICAgICAgICBlcnJvciA9IFRSVUUsICMgZG8gbm90IGludGVycnVwdCBjb2RlYm9vayBnZW5lcmF0aW9uIGluIGNhc2Ugb2YgZXJyb3JzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyB1c3VhbGx5IGJldHRlciBmb3IgZGVidWdnaW5nCiAgICAgICAgICAgICAgICAgICAgICBlY2hvID0gVFJVRSwgICMgc2hvdyBSIGNvZGUKICAgICAgICAgICAgICAgICAgICAgIGV2YWwgPSBUUlVFKQoKZ2dwbG90Mjo6dGhlbWVfc2V0KGdncGxvdDI6OnRoZW1lX21pbmltYWwoKSkKIyBwYW5kZXI6OnBhbmRlck9wdGlvbnMoInRhYmxlLnNwbGl0LnRhYmxlIiwgSW5mKQpsaWJyYXJ5KCJ3b3JjcyIpCmxpYnJhcnkoInJtYXJrZG93biIpCgpgYGAKCiMgRVJBLUNWRCAnZHJ1Z2dhYmxlLU1JLXRhcmdldHMnCgo8IS0tICFbRVJBLUNWRCBsb2dvXSgiVXNlcnMvc3d2YW5kZXJsYWFuL2lDbG91ZC9HZW5vbWljcy9Qcm9qZWN0cy8jRHJ1Z2dhYmxlLU1JLUdlbmVzL0FkbWluaXN0cmF0aW9uL0VSQS1DVkRcIExvZ29fQ01ZSy5qcGciKSAtLT4KCkZvciB0aGUgRVJBLUNWRCAnZHJ1Z2dhYmxlLU1JLXRhcmdldHMnIHByb2plY3QgKGdyYW50bnVtYmVyOiAwMUtMMTgwMikgd2UgcGVyZm9ybWVkIHR3byByZWxhdGVkIFJOQSBzZXF1ZW5jaW5nIChSTkFzZXEpIGV4cGVyaW1lbnRzOgoKMSkgIGNvbnZlbnRpb25hbCAoJ2J1bGsnKSBSTkFzZXEgdXNpbmcgUk5BIGV4dHJhY3RlZCBmcm9tIGNhcm90aWQgcGxhcXVlIHNhbXBsZXMsIG4gwrEgNzAwLiBBcyBvZiBgciBUb2RheS5SZXBvcnRgIGFsbCBzYW1wbGVzIGhhdmUgYmVlbiBzZWxlY3RlZCBhbmQKUk5BIGhhcyBiZWVuIGV4dHJhY3RlZDsgcXVhbGl0eSBjb250cm9sIChRQykgd2FzIHBlcmZvcm1lZCBhbmQgd2UgaGF2ZSBhIGRhdGFzZXQgb2YgNjM1IHNhbXBsZXMuCgoyKSAgc2luZ2xlLWNlbGwgUk5Bc2VxIChzY1JOQXNlcSkgb2YgYXQgbGVhc3QgbiA9IDQwIHNhbXBsZXMgKDIwIGZlbWFsZXMsIDIwIG1hbGVzKS4gQXMgb2YgYHIgVG9kYXkuUmVwb3J0YCBkYXRhIGlzIGF2YWlsYWJsZSBvZiA0MCBzYW1wbGVzICgzIGZlbWFsZXMsIDE1IG1hbGVzKSwgd2UgYXJlIGV4dGVuZGluZyBzYW1wbGluZyB0byBnZXQgbW9yZSBmZW1hbGUgc2FtcGxlcy4KClBsYXF1ZSBzYW1wbGVzIGFyZSBkZXJpdmVkIGZyb20gY2Fyb3RpZCBlbmRhcnRlcmVjdG9taWVzIGFzIHBhcnQgb2YgdGhlIFtBdGhlcm8tRXhwcmVzcyBCaW9iYW5rIFN0dWR5XShodHRwOnd3dy9hdGhlcm9leHByZXNzLm5sKSB3aGljaCBpcyBhbiBvbmdvaW5nIHN0dWR5IGluIHRoZSBVTUMgVXRyZWNodC4KCiMgQmFja2dyb3VuZAoKSGVyZSB3ZSBtYXAgdGhlIGByIFRSQUlUX09GX0lOVEVSRVNUYCB0byBzaW5nbGUtY2VsbHMgZnJvbSB0aGUgcGxhcXVlcy4KCiMjIFRhcmdldHMKCkhlcmUgd2Ugb2J0YWluIGRhdGEgZnJvbSB0aGUgYHIgVFJBSVRfT0ZfSU5URVJFU1RgIGluIHBsYXF1ZXMuCgpgYGB7ciB0YXJnZXRzLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KG9wZW54bHN4KQoKZ2VuZV9saXN0X2RmIDwtIHJlYWQueGxzeChwYXN0ZTAoUFJPSkVDVF9sb2MsICIvdGFyZ2V0cy90YXJnZXRzLnhsc3giKSwgc2hlZXQgPSAiR2VuZXMiKQoKZ2VuZV9saXN0IDwtIHVubGlzdChnZW5lX2xpc3RfZGYkR2VuZSkKZ2VuZV9saXN0CgpgYGAKCgojIExvYWQgZGF0YQoKRmlyc3Qgd2Ugd2lsbCBsb2FkIHRoZSBkYXRhOgoKLSAgIHNjUk5Bc2VxIGV4cGVyaW1lbnRhbCBkYXRhIGFuZCByZW5hbWUgdGhlIGNlbGwgdHlwZXMuCi0gICBBdGhlcm8tRXhwcmVzcyBjbGluaWNhbCBkYXRhLgoKSGVyZSB3ZSBsb2FkIHRoZSBsYXRlc3QgZGF0YXNldCBmcm9tIG91ciBBdGhlcm8tRXhwcmVzcyBzaW5nbGUtY2VsbCBSTkEgZXhwZXJpbWVudC4KCmBgYHtyIExvYWREYXRhfQoKIyBsb2FkKHBhc3RlMChBRVNDUk5BX2xvYywgIi8yMDIxMDgxMS40Ni5wYXRpZW50cy5LUC5SRGF0YSIpKQojIHNjUk5Bc2VxRGF0YSA8LSBzZXVzZXQKIyBybShzZXVzZXQpCiMgCiMgc2F2ZVJEUyhzY1JOQXNlcURhdGEsIHBhc3RlMChBRVNDUk5BX2xvYywgIi8yMDIxMDgxMS40Ni5wYXRpZW50cy5LUC5SRFMiKSkKCnNjUk5Bc2VxRGF0YSA8LSByZWFkUkRTKHBhc3RlMChBRVNDUk5BX2xvYywgIi8yMDIxMDgxMS40Ni5wYXRpZW50cy5LUC5SRFMiKSkKCnNjUk5Bc2VxRGF0YQoKYGBgCgpUaGUgbmFtaW5nL2NsYXNzaWZpY2F0aW9uIGlzIGJhc2VkIG9uIGEgY29tYmluYXRpb24gY29udmVudGlvbmFsIG1hcmtlcnMuIFdlIGRvIG5vdCBjbGFpbSB0byBrbm93IHRoZSBleGFjdCBpZGVudGl0eSBvZiBlYWNoIGNlbGwsIHJhdGhlciB3ZSByZWZlciB0byBjZWxscyBhcyAnS0lUKyBNYXN0IGNlbGxzIi1saWtlIGNlbGxzLiBMaWtld2lzZSB3ZSByZWZlciB0byB0aGUgY2VsbCBjbHVzdGVycyBhcyAnY29tbXVuaXRpZXMnIG9mIGNlbGxzIHRoYXQgZXhoaWJpdCBzaW1pbGFyIHByb3BlcnRpZXMsICppLmUuKiBzaW1pbGFyIGRlZmluaW5nIG1hcmtlcnMgKCplLmcuIEtJVCopLgoKV2Ugd2lsbCByZW5hbWUgdGhlIGNlbGwgdHlwZXMgdG8gaHVtYW4gcmVhZGFibGUgbmFtZXMuCgpgYGB7ciBDaGFuZ2UgY2VsbCBjdW1tdW5pdHkgbmFtZXN9CiMjIyBjaGFuZ2UgbmFtZXMgZm9yIGNsYXJpdHkKYmFja3VwLnNjUk5Bc2VxRGF0YSA9IHNjUk5Bc2VxRGF0YQojIGdldCB0aGUgb2xkIG5hbWVzIHRvIGNoYW5nZSB0byBuZXcgbmFtZXMKVU1BUFBsb3Qoc2NSTkFzZXFEYXRhLCBsYWJlbCA9IEZBTFNFLCBwdC5zaXplID0gMS4yNSwgbGFiZWwuc2l6ZSA9IDQsIGdyb3VwLmJ5ID0gImlkZW50IikKCmBgYAoKYGBge3J9CnVuaXF1ZShzY1JOQXNlcURhdGFAYWN0aXZlLmlkZW50KQpgYGAKCmBgYHtyfQpjZWxsdHlwZXMgPC0gYygiQ0Q2OCtDRDQrIE1vbm9jeXRlcyIgPSAiQ0Q2OCtDRDQrIE1vbm8iLCAKICAgICAgICAgICAgICAgIkNENjgrSUwxOCtUTFI0K1RSRU0yKyBSZXNpZGVudCBtYWNyb3BoYWdlcyIgPSAiQ0Q2OCtJTDE4K1RMUjQrVFJFTTIrIE1SZXMiLCAKICAgICAgICAgICAgICAgIkNENjgrQ0QxQysgRGVuZHJpdGljIENlbGxzIiA9ICJDRDY4K0NEMUMrIERDIiwKICAgICAgICAgICAgICAgIkNENjgrQ0FTUDErSUwxQitTRUxMKyBJbmZsYW1tYXRvcnkgbWFjcm9waGFnZXMiID0gIkNENjgrQ0FTUDErSUwxQitTRUxMIE1JbmYiLAogICAgICAgICAgICAgICAiQ0Q2OCtBQkNBMStPTFIxK1RSRU0yKyBGb2FtIENlbGxzIiA9ICJDRDY4K0FCQ0ExK09MUjErVFJFTTIrIEZDIiwKICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICMgVC1jZWxscwogICAgICAgICAgICAgICAiQ0QzKyBUIENlbGxzIEkiID0gIkNEMysgVEMgSSIsCiAgICAgICAgICAgICAgICJDRDMrIFQgQ2VsbHMgSUkiID0gIkNEMysgVEMgSUkiLCAKICAgICAgICAgICAgICAgIkNEMysgVCBDZWxscyBJSUkiID0gIkNEMysgVEMgSUlJIiwgCiAgICAgICAgICAgICAgICJDRDMrIFQgQ2VsbHMgSVYiID0gIkNEMysgVEMgSVYiLCAKICAgICAgICAgICAgICAgIkNEMysgVCBDZWxscyBWIiA9ICJDRDMrIFRDIFYiLCAKICAgICAgICAgICAgICAgIkNEMysgVCBDZWxscyBWSSIgPSAiQ0QzKyBUQyBWSSIsIAogICAgICAgICAgICAgICAiRk9YUDMrIFQgQ2VsbHMiID0gIkZPWFAzKyBUQyIsCiAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAjIEVuZG90aGVsaWFsIGNlbGxzCiAgICAgICAgICAgICAgICJDRDM0KyBFbmRvdGhlbGlhbCBDZWxscyBJIiA9ICJDRDM0KyBFQyBJIiwgCiAgICAgICAgICAgICAgICJDRDM0KyBFbmRvdGhlbGlhbCBDZWxscyBJSSIgPSAiQ0QzNCsgRUMgSUkiLCAKICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICMgU01DCiAgICAgICAgICAgICAgICJBQ1RBMisgU21vb3RoIE11c2NsZSBDZWxscyIgPSAiQUNUQTIrIFNNQyIsIAogICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIyBOSyBDZWxscwogICAgICAgICAgICAgICAiQ0QzK0NENTYrIE5LIENlbGxzIEkiID0gIkNEMytDRDU2KyBOSyBJIiwKICAgICAgICAgICAgICAgIkNEMytDRDU2KyBOSyBDZWxscyBJSSIgPSAiQ0QzK0NENTYrIE5LIElJIiwKICAgICAgICAgICAgICAgIyBNYXN0CiAgICAgICAgICAgICAgICJDRDY4K0tJVCsgTWFzdCBDZWxscyIgPSAiQ0Q2OCtLSVQrIE1DIiwKICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICJDRDc5QSsgQ2xhc3Mtc3dpdGNoZWQgTWVtb3J5IEIgQ2VsbHMiID0gIkNENzlBKyBCQ21lbSIsIAogICAgICAgICAgICAgICAiQ0Q3OSsgUGxhc21hIEIgQ2VsbHMiID0gIkNENzkrIEJDcGxhc21hIikKCnNjUk5Bc2VxRGF0YSA8LSBTZXVyYXQ6OlJlbmFtZUlkZW50cyhvYmplY3QgPSBzY1JOQXNlcURhdGEsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjZWxsdHlwZXMpCmBgYAoKYGBge3IgQ2hhbmdlIGNlbGwgY3VtbXVuaXR5IG5hbWVzIC0gbmV3IHBsb3R9ClVNQVBQbG90KHNjUk5Bc2VxRGF0YSwgbGFiZWwgPSBUUlVFLCBwdC5zaXplID0gMS4yNSwgbGFiZWwuc2l6ZSA9IDQsIGdyb3VwLmJ5ID0gImlkZW50IiwKICAgICAgICAgcmVwZWwgPSBUUlVFKQoKYGBgCgojIyBDbGluaWNhbCBkYXRhCgpMb2FkaW5nIHRoZSBBdGhlcm8tRXhwcmVzcyBjbGluaWNhbCBkYXRhLgoKYGBge3IgTG9hZEFFREJ9CkFFREIuQ0VBIDwtIHJlYWRSRFMoZmlsZSA9IHBhc3RlMChPVVRfbG9jLCAiLyIsIFRvZGF5LCIuIixQUk9KRUNUTkFNRSwiLkFFREIuQ0VBLlJEUyIpKQojIEFFREIuQ0VBIDwtIHJlYWRSRFMoZmlsZSA9IHBhc3RlMChPVVRfbG9jLCAiLzIwMjQwNTMxLiIsUFJPSkVDVE5BTUUsIi5BRURCLkNFQS5SRFMiKSkKCmBgYAoKCmBgYHtyIH0KIyBCYXNlbGluZSB0YWJsZSB2YXJpYWJsZXMKYmFzZXRhYmxlX3ZhcnMgPSBjKCJIb3NwaXRhbCIsICJPUnllYXIiLCAiQXJ0ZXJ5X3N1bW1hcnkiLAogICAgICAgICAgICAgICAgICAgIkFnZSIsICJHZW5kZXIiLCAKICAgICAgICAgICAgICAgICAgICMgIlRDX2ZpbmFsQ1UiLCAiTERMX2ZpbmFsQ1UiLCAiSERMX2ZpbmFsQ1UiLCAiVEdfZmluYWxDVSIsIAogICAgICAgICAgICAgICAgICAgIlRDX2ZpbmFsIiwgIkxETF9maW5hbCIsICJIRExfZmluYWwiLCAiVEdfZmluYWwiLCAKICAgICAgICAgICAgICAgICAgICMgImhzQ1JQX3BsYXNtYSIsCiAgICAgICAgICAgICAgICAgICAic3lzdG9saWMiLCAiZGlhc3RvbGkiLCAiR0ZSX01EUkQiLCAiQk1JIiwgCiAgICAgICAgICAgICAgICAgICAiS0RPUUkiLCAiQk1JX1dITyIsCiAgICAgICAgICAgICAgICAgICAiU21va2VyU3RhdHVzIiwgIkFsY29ob2xVc2UiLAogICAgICAgICAgICAgICAgICAgIkRpYWJldGVzU3RhdHVzIiwgCiAgICAgICAgICAgICAgICAgICAiSHlwZXJ0ZW5zaW9uLnNlbGZyZXBvcnQiLCAiSHlwZXJ0ZW5zaW9uLnNlbGZyZXBvcnRkcnVnIiwgIkh5cGVydGVuc2lvbi5jb21wb3NpdGUiLCAiSHlwZXJ0ZW5zaW9uLmRydWdzIiwgCiAgICAgICAgICAgICAgICAgICAiTWVkLmFudGljb2FndWxhbnRzIiwgIk1lZC5hbGwuYW50aXBsYXRlbGV0IiwgIk1lZC5TdGF0aW4uTExEIiwgCiAgICAgICAgICAgICAgICAgICAiU3Ryb2tlX0R4IiwgInN5bXB0IiwgIlN5bXB0b21zLjVHIiwgIkFzeW1wdFN5bXB0IiwgIkFzeW1wdFN5bXB0MkciLAogICAgICAgICAgICAgICAgICAgIlN5bXB0b21zLlVwZGF0ZTJHIiwgIlN5bXB0b21zLlVwZGF0ZTNHIiwgImluZGV4c3ltcHRvbXNfbGF0ZXN0XzRnIiwKICAgICAgICAgICAgICAgICAgICJyZXN0ZW5vcyIsICJzdGVub3NlIiwgCiAgICAgICAgICAgICAgICAgICAiQ0FEX2hpc3RvcnkiLCAiUEFPRCIsICJQZXJpcGhlcmFsLmludGVydiIsIAogICAgICAgICAgICAgICAgICAgIkVQX2NvbXBvc2l0ZSIsICJFUF9jb21wb3NpdGVfdGltZSIsICJFUF9tYWpvciIsICJFUF9tYWpvcl90aW1lIiwKICAgICAgICAgICAgICAgICAgICJNQUNfcmFua05vcm0iLCAiU01DX3JhbmtOb3JtIiwgIk1hY3JvcGhhZ2VzLmJpbiIsICJTTUMuYmluIiwKICAgICAgICAgICAgICAgICAgICJOZXV0cm9waGlsc19yYW5rTm9ybSIsICJNYXN0Q2VsbHNfcmFua05vcm0iLAogICAgICAgICAgICAgICAgICAgIklQSC5iaW4iLCAiVmVzc2VsRGVuc2l0eV9yYW5rTm9ybSIsCiAgICAgICAgICAgICAgICAgICAiQ2FsYy5iaW4iLCAiQ29sbGFnZW4uYmluIiwgCiAgICAgICAgICAgICAgICAgICAiRmF0LmJpbl8xMCIsICJGYXQuYmluXzQwIiwgIk92ZXJhbGxQbGFxdWVQaGVub3R5cGUiLCAiUGxhcXVlX1Z1bG5lcmFiaWxpdHlfSW5kZXgiLAogICAgICAgICAgICAgICAgICAgIlBDU0s5X3BsYXNtYSIsICJQQ1NLOV9wbGFzbWFfcmFua05vcm0iKQoKYmFzZXRhYmxlX2JpbiA9IGMoIkdlbmRlciIsICAiQXJ0ZXJ5X3N1bW1hcnkiLAogICAgICAgICAgICAgICAgICAiS0RPUUkiLCAiQk1JX1dITyIsCiAgICAgICAgICAgICAgICAgICJTbW9rZXJTdGF0dXMiLCAiQWxjb2hvbFVzZSIsCiAgICAgICAgICAgICAgICAgICJEaWFiZXRlc1N0YXR1cyIsIAogICAgICAgICAgICAgICAgICAiSHlwZXJ0ZW5zaW9uLnNlbGZyZXBvcnQiLCAiSHlwZXJ0ZW5zaW9uLnNlbGZyZXBvcnRkcnVnIiwgIkh5cGVydGVuc2lvbi5jb21wb3NpdGUiLCAiSHlwZXJ0ZW5zaW9uLmRydWdzIiwgCiAgICAgICAgICAgICAgICAgICJNZWQuYW50aWNvYWd1bGFudHMiLCAiTWVkLmFsbC5hbnRpcGxhdGVsZXQiLCAiTWVkLlN0YXRpbi5MTEQiLCAKICAgICAgICAgICAgICAgICAgIlN0cm9rZV9EeCIsICJzeW1wdCIsICJTeW1wdG9tcy41RyIsICJBc3ltcHRTeW1wdCIsICJBc3ltcHRTeW1wdDJHIiwKICAgICAgICAgICAgICAgICAgIlN5bXB0b21zLlVwZGF0ZTJHIiwgIlN5bXB0b21zLlVwZGF0ZTNHIiwgImluZGV4c3ltcHRvbXNfbGF0ZXN0XzRnIiwKICAgICAgICAgICAgICAgICAgInJlc3Rlbm9zIiwgInN0ZW5vc2UiLAogICAgICAgICAgICAgICAgICAiQ0FEX2hpc3RvcnkiLCAiUEFPRCIsICJQZXJpcGhlcmFsLmludGVydiIsIAogICAgICAgICAgICAgICAgICAiRVBfbWFqb3IiLCAiRVBfY29tcG9zaXRlIiwgIk1hY3JvcGhhZ2VzLmJpbiIsICJTTUMuYmluIiwKICAgICAgICAgICAgICAgICAgIklQSC5iaW4iLCAKICAgICAgICAgICAgICAgICAgIkNhbGMuYmluIiwgIkNvbGxhZ2VuLmJpbiIsIAogICAgICAgICAgICAgICAgICAiRmF0LmJpbl8xMCIsICJGYXQuYmluXzQwIiwgIk92ZXJhbGxQbGFxdWVQaGVub3R5cGUiLCAiUGxhcXVlX1Z1bG5lcmFiaWxpdHlfSW5kZXgiKQojIGJhc2V0YWJsZV9iaW4KCmJhc2V0YWJsZV9jb24gPSBiYXNldGFibGVfdmFyc1shYmFzZXRhYmxlX3ZhcnMgJWluJSBiYXNldGFibGVfYmluXQojIGJhc2V0YWJsZV9jb24KYGBgCgojIyBBRVNDUk5BOiBiYXNlbGluZSBjaGFyYWN0ZXJpc3RpY3MKCiMjIyBQcmVwYXJhdGlvbgoKYGBge3IgQmFzZWxpbmU6IGNyZWF0aW9ufQptZXRhZGF0YSA8LSBzY1JOQXNlcURhdGFAbWV0YS5kYXRhICU+JSBhc190aWJibGUoKSAlPiUgc2VwYXJhdGUob3JpZy5pZGVudCwgYygiUGF0aWVudCIsIE5BKSkKc2NSTkFzZXFEYXRhTWV0YSA8LSBtZXRhZGF0YSAlPiUgZGlzdGluY3QoUGF0aWVudCwgLmtlZXBfYWxsID0gVFJVRSkKCnNjUk5Bc2VxRGF0YU1ldGFBRSA8LSBtZXJnZShzY1JOQXNlcURhdGFNZXRhLCBBRURCLkNFQSwgYnkueCA9ICJQYXRpZW50IiwgYnkueSA9ICJTVFVEWV9OVU1CRVIiLCBzb3J0ID0gRkFMU0UsIGFsbC54ID0gVFJVRSkKZGltKHNjUk5Bc2VxRGF0YU1ldGFBRSkKCiMgUmVwbGFjZSBtaXNzaW5nIGRhdGEgCiMgUmVmOiBodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvbmFuaWFyL3ZpZ25ldHRlcy9yZXBsYWNlLXdpdGgtbmEuaHRtbApyZXF1aXJlKG5hbmlhcikKCm5hX3N0cmluZ3MgPC0gYygiTkEiLCAiTiBBIiwgIk4gLyBBIiwgIk4vQSIsICJOLyBBIiwgCiAgICAgICAgICAgICAgICAiTm90IEF2YWlsYWJsZSIsICJOb3QgYXZhaWxhYmxlIiwgCiAgICAgICAgICAgICAgICAibWlzc2luZyIsIAogICAgICAgICAgICAgICAgIi05OTkiLCAiLTk5IiwgCiAgICAgICAgICAgICAgICAiTm8gZGF0YSBhdmFpbGFibGUvbWlzc2luZyIsICJObyBkYXRhIGF2YWlsYWJsZS9NaXNzaW5nIikKIyBUaGVuIHlvdSB3cml0ZSB+LnggJWluJSBuYV9zdHJpbmdzIC0gd2hpY2ggcmVhZHMgYXMg4oCcZG9lcyB0aGlzIHZhbHVlIG9jY3VyIGluIHRoZSBsaXN0IG9mIE5BIHN0cmluZ3PigJ0uCgpzY1JOQXNlcURhdGFNZXRhQUUgJT4lCiAgcmVwbGFjZV93aXRoX25hX2FsbChjb25kaXRpb24gPSB+LnggJWluJSBuYV9zdHJpbmdzKQpgYGAKCmBgYHtyIH0KY2F0KCI9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09IikKY2F0KCJTRUxFQ1RJT04gVEhFIFNISVpaTEUiKQoKY2F0KCItIHNhbml0eSBjaGVja2luZyBQUklPUiB0byBzZWxlY3Rpb24iKQpsaWJyYXJ5KGRhdGEudGFibGUpCnJlcXVpcmUobGFiZWxsZWQpCmFlLmdlbmRlciA8LSB0b19mYWN0b3Ioc2NSTkFzZXFEYXRhTWV0YUFFJEdlbmRlcikKYWUuaG9zcGl0YWwgPC0gdG9fZmFjdG9yKHNjUk5Bc2VxRGF0YU1ldGFBRSRIb3NwaXRhbCkKdGFibGUoYWUuZ2VuZGVyLCBhZS5ob3NwaXRhbCwgZG5uID0gYygiU2V4IiwgIkhvc3BpdGFsIiksIHVzZU5BID0gImlmYW55IikKCmFlLmFydGVyeSA8LSB0b19mYWN0b3Ioc2NSTkFzZXFEYXRhTWV0YUFFJEFydGVyeV9zdW1tYXJ5KQp0YWJsZShhZS5hcnRlcnksIGFlLmdlbmRlciwgZG5uID0gYygiU2V4IiwgIkFydGVyeSIpLCB1c2VOQSA9ICJpZmFueSIpCgphZS5pYyA8LSB0b19mYWN0b3Ioc2NSTkFzZXFEYXRhTWV0YUFFJGluZm9ybWVkY29uc2VudCkKdGFibGUoYWUuaWMsIGFlLmdlbmRlciwgdXNlTkEgPSAiaWZhbnkiKQoKcm0oYWUuZ2VuZGVyLCBhZS5ob3NwaXRhbCwgYWUuYXJ0ZXJ5LCBhZS5pYykKCgpzY1JOQXNlcURhdGFNZXRhQUUuYWxsIDwtIHN1YnNldChzY1JOQXNlcURhdGFNZXRhQUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChBcnRlcnlfc3VtbWFyeSA9PSAiY2Fyb3RpZCAobGVmdCAmIHJpZ2h0KSIgfCBBcnRlcnlfc3VtbWFyeSA9PSAib3RoZXIgY2Fyb3RpZCBhcnRlcmllcyAoY29tbW9uLCBleHRlcm5hbCkiICkgJiAjIHdlIG9ubHkgd2FudCBjYXJvdGlkcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAibWlzc2luZyIgJiAjIHdlIGFyZSByZWFsbHkgc3RyaWN0IGluIHNlbGVjdGluZyBiYXNlZCBvbiAnaW5mb3JtZWQgY29uc2VudCchCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJubywgZGllZCIgJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyB0aXNzdWUsIG5vIGNvbW1lcmljYWwgYnVzaW5lc3MiICYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gInllcywgbm8gdGlzc3VlLCBubyBxdWVzdGlvbm5haXJlcywgbm8gbWVkaWNhbCBpbmZvLCBubyBjb21tZXJjaWFsIGJ1c2luZXNzIiAmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIG5vIHRpc3N1ZSwgbm8gcXVlc3Rpb25uYWlyZXMsIG5vIGhlYWx0aCB0cmVhdG1lbnQsIG5vIGNvbW1lcmljYWwgYnVzaW5lc3MiICYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gInllcywgbm8gdGlzc3VlLCBubyBxdWVzdGlvbm5haXJlcywgbm8gaGVhbHRoIHRyZWF0bWVudCwgbm8gbWVkaWNhbCBpbmZvLCBubyBjb21tZXJjaWFsIGJ1c2luZXNzIiAmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIG5vIHRpc3N1ZSwgbm8gaGVhbHRoIHRyZWF0bWVudCIgJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyB0aXNzdWUsIG5vIHF1ZXN0aW9ubmFpcmVzIiAmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIG5vIHRpc3N1ZSwgaGVhbHRoIHRyZWF0bWVudCB3aGVuIHBvc3NpYmxlIiAmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIG5vIHRpc3N1ZSIgJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyB0aXNzdWUsIG5vIHF1ZXN0aW9ubmFpcmVzLCBubyBoZWFsdGggdHJlYXRtZW50LCBubyBtZWRpY2FsIGluZm8iICYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gInllcywgbm8gdGlzc3VlLCBubyBxdWVzdGlvbm5haXJlcywgbm8gaGVhbHRoIHRyZWF0bWVudCwgbm8gY29tbWVyY2lhbCBidXNpbmVzcyIgJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAibm8sIGRvZXNuJ3Qgd2FudCB0byIgJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAibm8sIHVuYWJsZSB0byBzaWduIiAmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJubywgbm8gcmVhY3Rpb24iICYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gIm5vLCBsb3N0IiAmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJubywgdG9vIG9sZCIgJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyBtZWRpY2FsIGluZm8sIGhlYWx0aCB0cmVhdG1lbnQgd2hlbiBwb3NzaWJsZSIgJiAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gIm5vIChuZXZlciBhc2tlZCBmb3IgSUMgYmVjYXVzZSB0aGVyZSB3YXMgbm8gdGlzc3VlKSIgJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAibm8sIGVuZHBvaW50IiAmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJub29pdCBnZWluY2x1ZGVlcmQiICYgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIG5vIGhlYWx0aCB0cmVhdG1lbnQsIG5vIGNvbW1lcmNpYWwgYnVzaW5lc3MiICYgIyBJTVBPUlRBTlQ6IHNpbmNlIHdlIGFyZSBzaGFyaW5nIHdpdGggYSBjb21tZXJjaWFsIHBhcnR5CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIG5vIHRpc3N1ZSwgbm8gY29tbWVyaWNhbCBidXNpbmVzcyIgJiAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gInllcywgbm8gdGlzc3VlLCBubyBxdWVzdGlvbm5haXJlcywgbm8gbWVkaWNhbCBpbmZvLCBubyBjb21tZXJjaWFsIGJ1c2luZXNzIiAmIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyBxdWVzdGlvbm5haXJlcywgbm8gaGVhbHRoIHRyZWF0bWVudCwgbm8gY29tbWVyY2lhbCBidXNpbmVzcyIgJiAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gInllcywgbm8gdGlzc3VlLCBubyBxdWVzdGlvbm5haXJlcywgbm8gaGVhbHRoIHRyZWF0bWVudCwgbm8gY29tbWVyaWNhbCBidXNpbmVzcyIgJiAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gInllcywgbm8gaGVhbHRoIHRyZWF0bWVudCwgbm8gbWVkaWNhbCBpbmZvLCBubyBjb21tZXJjaWFsIGJ1c2luZXNzIiAmIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyB0aXNzdWUsIG5vIHF1ZXN0aW9ubmFpcmVzLCBubyBoZWFsdGggdHJlYXRtZW50LCBubyBtZWRpY2FsIGluZm8sIG5vIGNvbW1lcmNpYWwgYnVzaW5lc3MiICYgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIG5vIGNvbW1lcmljYWwgYnVzaW5lc3MiICYgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtZWRjb25zZW50ICE9ICJ5ZXMsIGhlYWx0aCB0cmVhdG1lbnQgd2hlbiBwb3NzaWJsZSwgbm8gY29tbWVyY2lhbCBidXNpbmVzcyIgJiAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gInllcywgbm8gbWVkaWNhbCBpbmZvLCBubyBjb21tZXJjaWFsIGJ1c2luZXNzIiAmIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyB0aXNzdWUsIG5vIHF1ZXN0aW9ubmFpcmVzLCBubyBoZWFsdGggdHJlYXRtZW50LCBubyBjb21tZXJjaWFsIGJ1c2luZXNzIiAmIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZm9ybWVkY29uc2VudCAhPSAieWVzLCBubyBxdWVzdGlvbm5haXJlcywgbm8gY29tbWVyY2lhbCBidXNpbmVzcyIgJiAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gInllcywgbm8gcXVlc3Rpb25uYWlyZXMsIGhlYWx0aCB0cmVhdG1lbnQgd2hlbiBwb3NzaWJsZSwgbm8gY29tbWVyY2lhbCBidXNpbmVzcyIgJiAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmZvcm1lZGNvbnNlbnQgIT0gInNlY29uZCBpbmZvcm1lZCBjb25jZW50czogeWVzLCBubyBjb21tZXJjaWFsIGJ1c2luZXNzIikKIyBzY1JOQXNlcURhdGFNZXRhQUUuYWxsWzE6MTAsIDE6MTBdCmRpbShzY1JOQXNlcURhdGFNZXRhQUUuYWxsKQojIERUOjpkYXRhdGFibGUoc2NSTkFzZXFEYXRhTWV0YUFFLmFsbCkKCmBgYAoKIyMjIEJhc2VsaW5lCgpTaG93aW5nIHRoZSBiYXNlbGluZSB0YWJsZSBmb3IgdGhlIHNjUk5Bc2VxIGRhdGEgaW4gMzkgQ0VBIHBhdGllbnRzIHdpdGgKaW5mb3JtZWQgY29uc2VudC4KCmBgYHtyIEJhc2VsaW5lOiBWaXN1YWxpemV9CmNhdCgiPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSIpCmNhdCgiQ1JFQVRFIEJBU0VMSU5FIFRBQkxFIikKCiMgQ3JlYXRlIGJhc2VsaW5lIHRhYmxlcwojIGh0dHA6Ly9yc3R1ZGlvLXB1YnMtc3RhdGljLnMzLmFtYXpvbmF3cy5jb20vMTMzMjFfZGEzMTQ2MzNkYjkyNGRjNzg5ODZhODUwODEzYTUwZDUuaHRtbApzY1JOQXNlcURhdGFNZXRhQUUuYWxsLnRhYmxlT25lID0gcHJpbnQoQ3JlYXRlVGFibGVPbmUodmFycyA9IGJhc2V0YWJsZV92YXJzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGZhY3RvclZhcnMgPSBiYXNldGFibGVfYmluLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgc3RyYXRhID0gIkdlbmRlciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IHNjUk5Bc2VxRGF0YU1ldGFBRS5hbGwsIGluY2x1ZGVOQSA9IFRSVUUpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub25ub3JtYWwgPSBjKCksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHF1b3RlID0gRkFMU0UsIHNob3dBbGxMZXZlbHMgPSBUUlVFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1hdCA9ICJwIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udERpZ2l0cyA9IDMpWywxOjJdCgpgYGAKCldyaXRpbmcgdGhlIGJhc2VsaW5lIHRhYmxlIHRvIEV4Y2VsIGZvcm1hdC4KCmBgYHtyIH0KIyBXcml0ZSBiYXNldGFibGUKcmVxdWlyZShvcGVueGxzeCkKIyB3cml0ZS54bHN4KGZpbGUgPSBwYXN0ZTAoQkFTRUxJTkVfbG9jLCAiLyIsVG9kYXksIi4iLFBST0pFQ1ROQU1FLCIuQUVTQ1JOQS4zMnB0cy5hZnRlcl9xYy5JQ19jb21tZXJjaWFsLkJhc2VsaW5lVGFibGUueGxzeCIpLCAKIyAgICAgICAgICAgIGZvcm1hdChhcy5kYXRhLmZyYW1lKHNjUk5Bc2VxRGF0YU1ldGFBRS5hbGwudGFibGVPbmUpLCBkaWdpdHMgPSA1LCBzY2llbnRpZmljID0gRkFMU0UpLAojICAgICAgICAgICAgcm93TmFtZXMgPSBUUlVFLCBjb2xOYW1lcyA9IFRSVUUsIAojICAgICAgICAgICAgc2hlZXROYW1lID0gIkFFU0NSTkEiLCBvdmVyd3JpdGUgPSBUUlVFKQp3cml0ZS54bHN4KGZpbGUgPSBwYXN0ZTAoQkFTRUxJTkVfbG9jLCAiLyIsVG9kYXksIi4iLFBST0pFQ1ROQU1FLCIuQUVTQ1JOQS5DRUEuMzlwdHMuYWZ0ZXJfcWMuSUNfYWNhZGVtaWMuQmFzZWxpbmVUYWJsZS54bHN4IiksCiAgICAgICAgICAgZm9ybWF0KGFzLmRhdGEuZnJhbWUoc2NSTkFzZXFEYXRhTWV0YUFFLmFsbC50YWJsZU9uZSksIGRpZ2l0cyA9IDUsIHNjaWVudGlmaWMgPSBGQUxTRSksCiAgICAgICAgICAgcm93TmFtZXMgPSBUUlVFLCBjb2xOYW1lcyA9IFRSVUUsCiAgICAgICAgICAgc2hlZXROYW1lID0gIkFFU0NSTkFfQ0VBIiwgb3ZlcndyaXRlID0gVFJVRSkKCmBgYAoKCiMgU3Vic2V0IHNjUk5Bc2VxIGRhdGEKCkxpc3Qgb2Ygc2FtcGxlcyB0byBiZSBpbmNsdWRlZCBiYXNlZCBvbiBpbmZvcm1lZCBjb25zZW50IChzZWUgYWJvdmUpLgoKYGBge3J9CnNhbXBsZXNfb2ZfaW50ZXJlc3QgPC0gdW5saXN0KHNjUk5Bc2VxRGF0YU1ldGFBRS5hbGwkUGF0aWVudCkKc2FtcGxlc19vZl9pbnRlcmVzdApgYGAKCkp1c3QgbWFrZSBzdXJlIHRvIGtlZXAgdGhlIHJvd3MgKGBwYXRpZW50aWRgLmBwbGF0ZWlkYC5gY2VsbGlkYCkgaW4gdGhlIGRhdGEsIHNvIHdlIHdpbGwgY3JlYXRlIGEgbmV3IGNvbHVtbiBmb3IgdGhhdC4KCmBgYHtyfQpzY1JOQXNlcURhdGEkY2VsbC5pZGVudCA8LSByb3duYW1lcyhzY1JOQXNlcURhdGFbW11dKQpgYGAKClN1YnNldHRpbmcgdGhlIHNhbXBsZXMgb2YgaW50ZXJlc3QgYmFzZWQgb24gYHNhbXBsZXNfb2ZfaW50ZXJlc3RgLgoKYGBge3J9CnNjUk5Bc2VxRGF0YUNFQTM5IDwtIHN1YnNldChzY1JOQXNlcURhdGEsIHN1YnNldCA9IFBhdGllbnQgJWluJSBzYW1wbGVzX29mX2ludGVyZXN0KQpgYGAKCgpTZWxlY3RpbmcgdGhlIGNsaW5pY2FsIGRhdGEgb2YgaW50ZXJlc3QuCgpgYGB7cn0KdmFyaWFibGVzX29mX2ludGVyZXN0IDwtIGMoIkhvc3BpdGFsIiwgIk9SeWVhciIsICJBcnRlcnlfc3VtbWFyeSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJBZ2UiLCAiR2VuZGVyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRDX2ZpbmFsIiwgIkxETF9maW5hbCIsICJIRExfZmluYWwiLCAiVEdfZmluYWwiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAic3lzdG9saWMiLCAiZGlhc3RvbGkiLCAiR0ZSX01EUkQiLCAiQk1JIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIktET1FJIiwgIkJNSV9XSE8iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAiU21va2VyU3RhdHVzIiwgIkFsY29ob2xVc2UiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAiRGlhYmV0ZXNTdGF0dXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAiSHlwZXJ0ZW5zaW9uLnNlbGZyZXBvcnQiLCAiSHlwZXJ0ZW5zaW9uLnNlbGZyZXBvcnRkcnVnIiwgIkh5cGVydGVuc2lvbi5jb21wb3NpdGUiLCAiSHlwZXJ0ZW5zaW9uLmRydWdzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1lZC5hbnRpY29hZ3VsYW50cyIsICJNZWQuYWxsLmFudGlwbGF0ZWxldCIsICJNZWQuU3RhdGluLkxMRCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJTdHJva2VfRHgiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAic3ltcHQiLCAiU3ltcHRvbXMuNUciLCAiQXN5bXB0U3ltcHQiLCAiQXN5bXB0U3ltcHQyRyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJTeW1wdG9tcy5VcGRhdGUyRyIsICJTeW1wdG9tcy5VcGRhdGUzRyIsICJpbmRleHN5bXB0b21zX2xhdGVzdF80ZyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJyZXN0ZW5vcyIsICJzdGVub3NlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNBRF9oaXN0b3J5IiwgIlBBT0QiLCAiUGVyaXBoZXJhbC5pbnRlcnYiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAiRVBfY29tcG9zaXRlIiwgIkVQX2NvbXBvc2l0ZV90aW1lIiwgIkVQX21ham9yIiwgIkVQX21ham9yX3RpbWUiKQoKdGVtcCA8LSBzdWJzZXQoc2NSTkFzZXFEYXRhTWV0YUFFLmFsbCwgc2VsZWN0ID0gYygiUGF0aWVudCIsIHZhcmlhYmxlc19vZl9pbnRlcmVzdCkpCmBgYAoKTm93IHdlIGFyZSBtZXJnaW5nIGluIHRoZSBjbGluaWNhbCBkYXRhIG9mIGludGVyZXN0LgoKYGBge3J9CiMgU3RlcCAxOiBFeHRyYWN0IG9yaWdpbmFsIG1ldGFkYXRhIGZyb20gU2V1cmF0IG9iamVjdApvcmlnaW5hbF9tZXRhZGF0YV9kZiA8LSBzY1JOQXNlcURhdGFDRUEzOUBtZXRhLmRhdGEKCiMgU3RlcCAyOiBNZXJnZSB3aXRoIGRhdGFmcmFtZSAodGVtcCkgd2l0aCBzZWxlY3QgdmFyaWFibGVzIGJhc2VkIG9uICdQYXRpZW50JyBjb2x1bW4KbWVyZ2VkX21ldGFkYXRhX2RmIDwtIG1lcmdlKG9yaWdpbmFsX21ldGFkYXRhX2RmLCB0ZW1wLCBieSA9ICJQYXRpZW50IiwgYWxsLnggPSBUUlVFLCBzb3J0ID0gRkFMU0UpCgojIFN0ZXAgMzogRXhjbHVkZSBhbHJlYWR5IGV4aXN0aW5nIGNvbHVtbnMgdG8gYXZvaWQgZHVwbGljYXRpb24KbmV3X21ldGFkYXRhX2NvbHVtbnMgPC0gc2V0ZGlmZihjb2xuYW1lcyh0ZW1wKSwgY29sbmFtZXMob3JpZ2luYWxfbWV0YWRhdGFfZGYpKQpuZXdfbWV0YV9pbmZvX2RmIDwtIG1lcmdlZF9tZXRhZGF0YV9kZlssIG5ld19tZXRhZGF0YV9jb2x1bW5zLCBkcm9wID0gRkFMU0VdCgojIFN0ZXAgNDogQWRkIHRoZSBuZXcgbWV0YWRhdGEgdG8gdGhlIFNldXJhdCBvYmplY3QKc2NSTkFzZXFEYXRhQ0VBMzkgPC0gQWRkTWV0YURhdGEoc2NSTkFzZXFEYXRhQ0VBMzksIG1ldGFkYXRhID0gbmV3X21ldGFfaW5mb19kZikKCiMgU3RlcCA1OiBSZW5hbWUgYFBhdGllbnRgIHRvIGBTVFVEWV9OVU1CRVJgIHRvIG1hdGNoIHRoZSBjbGluaWNhbCBkYXRhCnNjUk5Bc2VxRGF0YUNFQTM5QG1ldGEuZGF0YSA8LSBkcGx5cjo6cmVuYW1lKHNjUk5Bc2VxRGF0YUNFQTM5QG1ldGEuZGF0YSwgIlNUVURZX05VTUJFUiIgPSAiUGF0aWVudCIpCgojIFZlcmlmeSB0aGF0IHRoZSBuZXcgbWV0YWRhdGEgd2FzIGFkZGVkIGNvcnJlY3RseQpoZWFkKHNjUk5Bc2VxRGF0YUNFQTM5QG1ldGEuZGF0YSkKCmBgYAoKIyMgU2F2aW5nIG5ldyBkYXRhc2V0CgpgYGB7cn0KdGVtcDIgPC0gYXNfdGliYmxlKHN1YnNldChzY1JOQXNlcURhdGFDRUEzOUBtZXRhLmRhdGEsIHNlbGVjdCA9IGMoIlNUVURZX05VTUJFUiIsICJvcmlnLmlkZW50IiwgIm5Db3VudF9STkEiLCAibkZlYXR1cmVfUk5BIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUGxhdGUiLCAiQmF0Y2giLCAiQy5IIiwgIlR5cGUiLCAicGVyY2VudC5tdCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm5Db3VudF9TQ1QiLCAibkZlYXR1cmVfU0NUIiwgInNldXJhdF9jbHVzdGVycyIpKSkKCiMgZndyaXRlKHRlbXAyLAojICAgICAgICBmaWxlID0gcGFzdGUwKE9VVF9sb2MsICIvIiwgVG9kYXksICIuQUVTQ1JOQS5DRUEuMzlwdHMuc2FtcGxlbGlzdC5hZnRlcl9xYy5JQ19jb21tZXJjaWFsLmNzdiIpLAojICAgICAgICBzZXAgPSAiLCIsIHJvdy5uYW1lcyA9IEZBTFNFLCBjb2wubmFtZXMgPSBUUlVFLAojICAgICAgICBzaG93UHJvZ3Jlc3MgPSBUUlVFKQojIHJtKHRlbXAyKQojIAojIHRlbXAgPC0gZHBseXI6OnJlbmFtZSh0ZW1wLCAiU1RVRFlfTlVNQkVSIiA9ICJQYXRpZW50IikKIyBmd3JpdGUodGVtcCwKIyAgICAgICAgZmlsZSA9IHBhc3RlMChPVVRfbG9jLCAiLyIsIFRvZGF5LCAiLkFFU0NSTkEuQ0VBLjM5cHRzLmNsaW5pY2FsZGF0YS5hZnRlcl9xYy5JQ19jb21tZXJjaWFsLmNzdiIpLAojICAgICAgICBzZXAgPSAiLCIsIHJvdy5uYW1lcyA9IEZBTFNFLCBjb2wubmFtZXMgPSBUUlVFLAojICAgICAgICBzaG93UHJvZ3Jlc3MgPSBUUlVFKQojIHJtKHRlbXApCiMgCiMgc2F2ZVJEUyhzY1JOQXNlcURhdGFDRUEzOSwgZmlsZSA9IHBhc3RlMChPVVRfbG9jLCAiLyIsIFRvZGF5LCAiLkFFU0NSTkEuQ0VBLjM5cHRzLlNldXJhdC5hZnRlcl9xYy5JQ19jb21tZXJjaWFsLlJEUyIpKQoKZndyaXRlKHRlbXAyLAogICAgICAgZmlsZSA9IHBhc3RlMChPVVRfbG9jLCAiLyIsIFRvZGF5LCAiLkFFU0NSTkEuQ0VBLjM5cHRzLnNhbXBsZWxpc3QuYWZ0ZXJfcWMuSUNfYWNhZGVtaWMuY3N2IiksCiAgICAgICBzZXAgPSAiLCIsIHJvdy5uYW1lcyA9IEZBTFNFLCBjb2wubmFtZXMgPSBUUlVFLAogICAgICAgc2hvd1Byb2dyZXNzID0gVFJVRSkKcm0odGVtcDIpCgp0ZW1wIDwtIGRwbHlyOjpyZW5hbWUodGVtcCwgIlNUVURZX05VTUJFUiIgPSAiUGF0aWVudCIpCmZ3cml0ZSh0ZW1wLAogICAgICAgZmlsZSA9IHBhc3RlMChPVVRfbG9jLCAiLyIsIFRvZGF5LCAiLkFFU0NSTkEuQ0VBLjM5cHRzLmNsaW5pY2FsZGF0YS5hZnRlcl9xYy5JQ19hY2FkZW1pYy5jc3YiKSwKICAgICAgIHNlcCA9ICIsIiwgcm93Lm5hbWVzID0gRkFMU0UsIGNvbC5uYW1lcyA9IFRSVUUsCiAgICAgICBzaG93UHJvZ3Jlc3MgPSBUUlVFKQpybSh0ZW1wKQoKc2F2ZVJEUyhzY1JOQXNlcURhdGFDRUEzOSwgZmlsZSA9IHBhc3RlMChPVVRfbG9jLCAiLyIsIFRvZGF5LCAiLkFFU0NSTkEuQ0VBLjM5cHRzLlNldXJhdC5hZnRlcl9xYy5JQ19hY2FkZW1pYy5SRFMiKSkKCmBgYAoKCiMgQUVTQ1JOQQoKIyMgUXVhbGl0eSBjb250cm9sCgpIZXJlIHJldmlldyB0aGUgbnVtYmVyIG9mIGNlbGxzIHBlciBzYW1wbGUsIHBsYXRlLCBhbmQgcGF0aWVudHMuIEFuZCBwbG90IHRoZQpyYXRpbydzIHBlciBzYW1wbGUgYW5kIHN0dWR5IG51bWJlci4KCmBgYHtyIFF1YWxpdHlDb250cm9sfQojIyBjaGVjayBzdHVmZgpjYXQoIlxuSG93IG1hbnkgY2VsbHMgcGVyIHR5cGUgLi4uPyIpCnNvcnQodGFibGUoc2NSTkFzZXFEYXRhQ0VBMzlAbWV0YS5kYXRhJFNDVF9zbm5fcmVzLjEuMjUpKQoKIyBjYXQoIlxuXG5Ib3cgbWFueSBjZWxscyBwZXIgcGxhdGUgLi4uPyIpCiMgc29ydCh0YWJsZShzY1JOQXNlcURhdGFDRUEzOUBtZXRhLmRhdGEkSUQpKQoKIyBjYXQoIlxuXG5Ib3cgbWFueSBjZWxscyBwZXIgdHlwZSBwZXIgcGxhdGUgLi4uPyIpCiMgdGFibGUoc2NSTkFzZXFEYXRhQ0VBMzlAbWV0YS5kYXRhJFNDVF9zbm5fcmVzLjAuOCwgc2NSTkFzZXFEYXRhQ0VBMzlAbWV0YS5kYXRhJElEKQoKY2F0KCJcblxuSG93IG1hbnkgY2VsbHMgcGVyIHBhdGllbnQgLi4uPyIpCnNvcnQodGFibGUoc2NSTkFzZXFEYXRhQ0VBMzlAbWV0YS5kYXRhJFNUVURZX05VTUJFUikpCgpjYXQoIlxuXG5WaXN1YWxpemluZyB0aGVzZSByYXRpbydzIHBlciBzdHVkeSBudW1iZXIgYW5kIHNhbXBsZSAuLi4/IikKVU1BUFBsb3Qoc2NSTkFzZXFEYXRhQ0VBMzksIGxhYmVsID0gVFJVRSwgcHQuc2l6ZSA9IDEuMjUsIGxhYmVsLnNpemUgPSA0LCBncm91cC5ieSA9ICJpZGVudCIsCiAgICAgICAgIHJlcGVsID0gVFJVRSkKZ2dzYXZlKHBhc3RlMChQTE9UX2xvYywgIi8iLCBUb2RheSwgIi5VTUFQLnBuZyIpLCBwbG90ID0gbGFzdF9wbG90KCkpCmdnc2F2ZShwYXN0ZTAoUExPVF9sb2MsICIvIiwgVG9kYXksICIuVU1BUC5wcyIpLCBwbG90ID0gbGFzdF9wbG90KCkpCgoKIyBiYXJwbG90KHByb3AudGFibGUoeCA9IHRhYmxlKHNjUk5Bc2VxRGF0YUNFQTM5QGFjdGl2ZS5pZGVudCwgc2NSTkFzZXFEYXRhQ0VBMzlAbWV0YS5kYXRhJFBhdGllbnQpKSwgCiMgICAgICAgICBjZXguYXhpcyA9IDEuMCwgY2V4Lm5hbWVzID0gMC41LCBsYXMgPSAxLAojICAgICAgICAgY29sID0gdWl0aG9mX2NvbG9yLCB4bGFiID0gInN0dWR5IG51bWJlciIsIGxlZ2VuZC50ZXh0ID0gRkFMU0UsIGFyZ3MubGVnZW5kID0gbGlzdCh4ID0gImJvdHRvbSIpKQojIGRldi5jb3B5KHBkZiwgcGFzdGUwKFFDX2xvYywgIi8iLCBUb2RheSwgIi5jZWxsX3JhdGlvc19wZXJfc2FtcGxlLnBkZiIpKQojIGRldi5vZmYoKQoKIyBiYXJwbG90KHByb3AudGFibGUoeCA9IHRhYmxlKHNjUk5Bc2VxRGF0YUNFQTM5QGFjdGl2ZS5pZGVudCwgc2NSTkFzZXFEYXRhQ0VBMzlAbWV0YS5kYXRhJElEKSksIAojICAgICAgICAgY2V4LmF4aXMgPSAxLjAsIGNleC5uYW1lcyA9IDAuNSwgbGFzID0gMiwKIyAgICAgICAgIGNvbCA9IHVpdGhvZl9jb2xvciwgeGxhYiA9ICJzYW1wbGUgSUQiLCBsZWdlbmQudGV4dCA9IEZBTFNFLCBhcmdzLmxlZ2VuZCA9IGxpc3QoeCA9ICJib3R0b20iKSkKIyBkZXYuY29weShwZGYsIHBhc3RlMChRQ19sb2MsICIvIiwgVG9kYXksICIuY2VsbF9yYXRpb3NfcGVyX3NhbXBsZV9wZXJfcGxhdGUucGRmIikpCiMgZGV2Lm9mZigpCgpgYGAKCiMjIFZpc3VhbGlzYXRpb25zCgojIyMgRmVhdHVyZSBwbG90cyBvZiBrbm93biBjZWxsdWxhciBtYXJrZXJzCgpMZXQncyBwcm9qZWN0IGtub3duIGNlbGx1bGFyIG1hcmtlcnMuCgpgYGB7ciBWaXN1YWxpc2F0aW9uOiB0U05FIEV4cGxvcmF0aW9ufQpVTUFQUGxvdChzY1JOQXNlcURhdGFDRUEzOSwgbGFiZWwgPSBGQUxTRSwgcHQuc2l6ZSA9IDEuMjUsIGxhYmVsLnNpemUgPSA0LCBncm91cC5ieSA9ICJpZGVudCIsCiAgICAgICAgIHJlcGVsID0gVFJVRSkKCiMgZW5kb3RoZWxpYWwgY2VsbHMKRmVhdHVyZVBsb3Qoc2NSTkFzZXFEYXRhQ0VBMzksIGZlYXR1cmVzID0gYygiQ0QzNCIpLCBjb2xzID0gIGMoIiNFQ0VDRUMiLCAiI0RCMDAzRiIpKQpGZWF0dXJlUGxvdChzY1JOQXNlcURhdGFDRUEzOSwgZmVhdHVyZXMgPSBjKCJFRE4xIiksIGNvbHMgPSAgYygiI0VDRUNFQyIsICIjREIwMDNGIikpCkZlYXR1cmVQbG90KHNjUk5Bc2VxRGF0YUNFQTM5LCBmZWF0dXJlcyA9IGMoIkVETlJBIiwgIkVETlJCIiksIGNvbHMgPSAgYygiI0VDRUNFQyIsICIjREIwMDNGIikpCkZlYXR1cmVQbG90KHNjUk5Bc2VxRGF0YUNFQTM5LCBmZWF0dXJlcyA9IGMoIkNESDUiLCAiUEVDQU0xIiksIGNvbHMgPSAgYygiI0VDRUNFQyIsICIjREIwMDNGIikpCkZlYXR1cmVQbG90KHNjUk5Bc2VxRGF0YUNFQTM5LCBmZWF0dXJlcyA9IGMoIkFDS1IxIiksIGNvbHMgPSAgYygiI0VDRUNFQyIsICIjREIwMDNGIikpCgojIFNNQwpGZWF0dXJlUGxvdChzY1JOQXNlcURhdGFDRUEzOSwgZmVhdHVyZXMgPSBjKCJNWUgxMSIpLCBjb2xzID0gIGMoIiNFQ0VDRUMiLCAiI0RCMDAzRiIpKQpGZWF0dXJlUGxvdChzY1JOQXNlcURhdGFDRUEzOSwgZmVhdHVyZXMgPSBjKCJMR0FMUzMiLCAiQUNUQTIiKSwgY29scyA9ICBjKCIjRUNFQ0VDIiwgIiNEQjAwM0YiKSkKCiMgbWFjcm9waGFnZXMKRmVhdHVyZVBsb3Qoc2NSTkFzZXFEYXRhQ0VBMzksIGZlYXR1cmVzID0gYygiQ0QxNCIsICJDRDY4IiksIGNvbHMgPSAgYygiI0VDRUNFQyIsICIjREIwMDNGIikpCkZlYXR1cmVQbG90KHNjUk5Bc2VxRGF0YUNFQTM5LCBmZWF0dXJlcyA9IGMoIkNEMzYiKSwgY29scyA9ICBjKCIjRUNFQ0VDIiwgIiNEQjAwM0YiKSkKCiMgdC1jZWxscwpGZWF0dXJlUGxvdChzY1JOQXNlcURhdGFDRUEzOSwgZmVhdHVyZXMgPSBjKCJDRDNFIiksIGNvbHMgPSAgYygiI0VDRUNFQyIsICIjREIwMDNGIikpCkZlYXR1cmVQbG90KHNjUk5Bc2VxRGF0YUNFQTM5LCBmZWF0dXJlcyA9IGMoIkNENCIpLCBjb2xzID0gIGMoIiNFQ0VDRUMiLCAiI0RCMDAzRiIpKQojIEZlYXR1cmVQbG90KHNjUk5Bc2VxRGF0YUNFQTM5LCBmZWF0dXJlcyA9IGMoIkNEOCIpLCBjb2xzID0gIGMoIiNFQ0VDRUMiLCAiI0RCMDAzRiIpKQoKIyBiLWNlbGxzCkZlYXR1cmVQbG90KHNjUk5Bc2VxRGF0YUNFQTM5LCBmZWF0dXJlcyA9IGMoIkNENzlBIiksIGNvbHMgPSAgYygiI0VDRUNFQyIsICIjREIwMDNGIikpCgojIG1hc3QgY2VsbHMKRmVhdHVyZVBsb3Qoc2NSTkFzZXFEYXRhQ0VBMzksIGZlYXR1cmVzID0gYygiS0lUIiksIGNvbHMgPSAgYygiI0VDRUNFQyIsICIjREIwMDNGIikpCgojIE5LIGNlbGxzCkZlYXR1cmVQbG90KHNjUk5Bc2VxRGF0YUNFQTM5LCBmZWF0dXJlcyA9IGMoIk5DQU0xIiksIGNvbHMgPSAgYygiI0VDRUNFQyIsICIjREIwMDNGIikpCgpgYGAKCiMjIFRhcmdldHMgb2YgaW50ZXJlc3Q6CgpXZSBjaGVjayB3aGV0aGVyIHRoZSB0YXJnZXRzIGdlbmVzIHdlcmUgc2VxdWVuY2VkIHVzaW5nIG91ciBtZXRob2QuIEluIGNhc2Ugc29tZSBnZW5lcyBhcmUgbm90IGF2YWlsYWJsZSBpbiBvdXIgZGF0YSB3ZSBjb3VsZCBmaWx0ZXIgdGhlbSBoZXJlLgoKYGBge3IgbGlzdCB0YXJnZXQgZ2VuZXN9CnRhcmdldF9nZW5lcyA8LSBnZW5lX2xpc3QKdGFyZ2V0X2dlbmVzCmBgYAoKCkhlcmUgd2UgZmlsdGVyIC0gaWYgbmVlZGVkIC0gZ2VuZXMgbm90IHByZXNlbnQgaW4gdGhlIGRhdGE7IGFsbCBnZW5lcyBhcmUgcHJlc2VudCB0aG91Z2guIAoKYGBge3IgVmlzdWFsaXNhdGlvbjogcHJlcGFyYXRpb259CgpnZW5lX2xpc3Rfcm0gPC0gYygiIikgCgp0ZW1wID0gdGFyZ2V0X2dlbmVzWyF0YXJnZXRfZ2VuZXMgJWluJSBnZW5lX2xpc3Rfcm1dCgp0YXJnZXRfZ2VuZXNfcWMgPC0gYyh0ZW1wKQoKIyBnZW5lX2xpc3RfcWMgPC0gZ2VuZV9saXN0CiMgCiMgZm9yIGRlYnVnCiMgZ2VuZV9saXN0X3FjX3JlcGxhY2UgPC0gYygiTVJURkEiKQoKIyB0YXJnZXRfZ2VuZXNfcWMgPC0gdGFyZ2V0X2dlbmVzCnRhcmdldF9nZW5lc19xYwoKYGBgCgoKIyMjIEV4cHJlc3Npb24gaW4gY2VsbCBjb21tdW5pdGllcwoKYGBge3IgVmlzdWFsaXNhdGlvbjogVGFyZ2V0cyBEb3QgUGxvdHMsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmxpYnJhcnkoUkNvbG9yQnJld2VyKQoKcDEgPC0gRG90UGxvdChzY1JOQXNlcURhdGFDRUEzOSwgCiAgICAgICAgICAgICAgZmVhdHVyZXMgPSB0YXJnZXRfZ2VuZXNfcWMsCiAgICAgICAgICAgICAgY29scyA9ICJSZEJ1IikgKyAKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdD0xLCBzaXplID0gOCkpICsKICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCksIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfYmxhbmsoKSkgIyByZW1vdmUgdGhlIHktIGFuZCB4LWF4aXMgbGFiZWxzCgpwMQoKZ2dzYXZlKHBhc3RlMChQTE9UX2xvYywgIi8iLCBUb2RheSwgIi5Eb3RQbG90LlRhcmdldHMucG5nIiksIHBsb3QgPSBsYXN0X3Bsb3QoKSkKZ2dzYXZlKHBhc3RlMChQTE9UX2xvYywgIi8iLCBUb2RheSwgIi5Eb3RQbG90LlRhcmdldHMucHMiKSwgcGxvdCA9IGxhc3RfcGxvdCgpKQpnZ3NhdmUocGFzdGUwKFBMT1RfbG9jLCAiLyIsIFRvZGF5LCAiLkRvdFBsb3QuVGFyZ2V0cy5wZGYiKSwgcGxvdCA9IGxhc3RfcGxvdCgpKQoKcm0ocDEpCmBgYAoKTGV0J3MgZ3JvdXAgdGhpcyBkb3RwbG90IGJhc2VkIG9uIHNvbWUgZ3JvdXBpbmcuCgpJZiB3ZSB3YW50IHdlIGNhbiBhbHNvIGZpbHRlciB0aGUgZ2VuZXMgdGhhdCBhcmUgbm90IGZvdW5kIGluIHRoZSBkYXRhLgoKYGBge3J9CiMgQXNzdW1pbmcgJ2dlbmVfbGlzdF9kZicgaXMgeW91ciBkYXRhLmZyYW1lIHdpdGggdGhlIHJlbGV2YW50IGNvbHVtbnMgbG9hZGVkCmdlbmVfbGlzdF9kZl9maWx0ZXJlZCA8LSBzdWJzZXQoZ2VuZV9saXN0X2RmLCBDb21tZW50cyAhPSAibm90IGZvdW5kIiB8IGlzLm5hKENvbW1lbnRzKSkKZ2VuZV9saXN0X2RmX2ZpbHRlcmVkCmBgYAoKIyMjIEV4cHJlc3Npb24gaW4gY2VsbCBjb21tdW5pdGllcyBncm91cGVkCgpgYGB7cn0KIyBTZXBhcmF0ZSBnZW5lcyBieSBzaWduaWZpY2FuY2UKZ2VuZV9saXN0X2RmX2ZpbHRlcmVkX3VwIDwtIGdlbmVfbGlzdF9kZl9maWx0ZXJlZCRHZW5lU3ltYm9sW2dlbmVfbGlzdF9kZl9maWx0ZXJlZCRHcm91cCA9PSAiVVAiXQpnZW5lX2xpc3RfZGZfZmlsdGVyZWRfZG93biA8LSBnZW5lX2xpc3RfZGZfZmlsdGVyZWQkR2VuZVN5bWJvbFtnZW5lX2xpc3RfZGZfZmlsdGVyZWQkR3JvdXAgPT0gIkRPV04iXQoKIyBDb21iaW5lIHRoZSBnZW5lcywgZmlyc3QgRE9XTiB0aGVuIFVQIChvciB2aWNlIHZlcnNhIGJhc2VkIG9uIHByZWZlcmVuY2UpCm9yZGVyZWRfZ2VuZXNfcWMgPC0gYyhnZW5lX2xpc3RfZGZfZmlsdGVyZWRfdXAsIGdlbmVfbGlzdF9kZl9maWx0ZXJlZF9kb3duKQpgYGAKCgpgYGB7cn0KbGlicmFyeShSQ29sb3JCcmV3ZXIpCiMgQ3JlYXRlIERvdFBsb3Qgb3JkZXJlZApwMV9ncm91cCA8LSBEb3RQbG90KHNjUk5Bc2VxRGF0YSwgCiAgICAgICAgICAgICAgZmVhdHVyZXMgPSBvcmRlcmVkX2dlbmVzX3FjLCAKICAgICAgICAgICAgICBjb2xzID0gIlJkQnUiKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0PTEsIHNpemUgPSA4KSkgKwogIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy50aXRsZS55ID0gZWxlbWVudF9ibGFuaygpKSAjIHJlbW92ZSB0aGUgeS0gYW5kIHgtYXhpcyBsYWJlbHMKCnAxX2dyb3VwCgojIFNhdmUgdGhlIHBsb3RzCmdnc2F2ZShwYXN0ZTAoUExPVF9sb2MsICIvIiwgVG9kYXksICIuRG90UGxvdC5UYXJnZXRzLkdyb3VwZWQucG5nIiksIHBsb3QgPSBwMV9ncm91cCkKZ2dzYXZlKHBhc3RlMChQTE9UX2xvYywgIi8iLCBUb2RheSwgIi5Eb3RQbG90LlRhcmdldHMuR3JvdXBlZC5wcyIpLCBwbG90ID0gcDFfZ3JvdXApCmdnc2F2ZShwYXN0ZTAoUExPVF9sb2MsICIvIiwgVG9kYXksICIuRG90UGxvdC5UYXJnZXRzLkdyb3VwZWQucGRmIiksIHBsb3QgPSBwMV9ncm91cCkKCmBgYAoKIyMjIyBQbG90dGluZyBnZW5kZXIKCldlIHNob3VsZCBhbHNvIHBsb3QgdGhlc2UgZGF0YSBzdHJhdGlmaWVkIGJ5IGdlbmRlciBzbW9vdGggbXVzY2xlIGNlbGxzLgoKIyMjIyMgQ3JlYXRlIHN1YnNldHMKCmBgYHtyfQp1bmlxdWUoc2NSTkFzZXFEYXRhQ0VBMzkkR2VuZGVyKQpgYGAKCmBgYHtyfQojIFN1YnNldCBTZXVyYXQgb2JqZWN0IGZvciBEaWFiZXRpYyBQYXRpZW50cwptYWxlX2NlbGxzIDwtIFdoaWNoQ2VsbHMoc2NSTkFzZXFEYXRhQ0VBMzksIGV4cHJlc3Npb24gPSBHZW5kZXIgPT0gIm1hbGUiKQpzY1JOQXNlcURhdGFDRUEzOV9tYWxlcyA8LSBzdWJzZXQoc2NSTkFzZXFEYXRhQ0VBMzksIGNlbGxzID0gbWFsZV9jZWxscykKCiMgU3Vic2V0IFNldXJhdCBvYmplY3QgZm9yIE5vbi1EaWFiZXRpYyBQYXRpZW50cwpmZW1hbGVfY2VsbHMgPC0gV2hpY2hDZWxscyhzY1JOQXNlcURhdGFDRUEzOSwgZXhwcmVzc2lvbiA9IEdlbmRlciA9PSAiZmVtYWxlIikKc2NSTkFzZXFEYXRhQ0VBMzlfZmVtYWxlcyA8LSBzdWJzZXQoc2NSTkFzZXFEYXRhQ0VBMzksIGNlbGxzID0gZmVtYWxlX2NlbGxzKQoKYGBgCgojIyMjIyBTbW9vdGggbXVzY2xlIGNlbGxzCgpgYGB7cn0KIyBEZWZpbmUgdGhlIGNlbGwgaWRlbnRpdGllcyB5b3Ugd2FudCB0byBpbmNsdWRlIGluIHRoZSBwbG90CnNlbGVjdGVkX2lkZW50c19zbWEgPC0gYygiQUNUQTIrIFNNQyIpCmBgYAoKYGBge3J9CmxpYnJhcnkoUkNvbG9yQnJld2VyKQpsaWJyYXJ5KGNvd3Bsb3QpICAjIEZvciBjb21iaW5pbmcgcGxvdHMKCiMgQ3JlYXRlIERvdFBsb3QgZm9yIG1hbGVzCnAxX21hbGVzX3NtYSA8LSBEb3RQbG90KHNjUk5Bc2VxRGF0YUNFQTM5X21hbGVzLAogICAgICAgICAgICAgICAgICAgICAgIGZlYXR1cmVzID0gb3JkZXJlZF9nZW5lc19xYywKICAgICAgICAgICAgICAgICAgICAgICBpZGVudHMgPSBzZWxlY3RlZF9pZGVudHNfc21hLCAKICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICBjb2xzID0gIlJkQnUiKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSwgc2l6ZSA9IDgpKSArCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLCBheGlzLnRpdGxlLnkgPSBlbGVtZW50X2JsYW5rKCkpICsgCiAgZ2d0aXRsZSgiTWFsZXMiKQoKIyBDcmVhdGUgRG90UGxvdCBmb3IgZmVtYWxlcwpwMl9mZW1hbGVzX3NtYSA8LSBEb3RQbG90KHNjUk5Bc2VxRGF0YUNFQTM5X2ZlbWFsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZlYXR1cmVzID0gb3JkZXJlZF9nZW5lc19xYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgaWRlbnRzID0gc2VsZWN0ZWRfaWRlbnRzX3NtYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbHMgPSAiUmRCdSIpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxLCBzaXplID0gOCkpICsKICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCksIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfYmxhbmsoKSkgKyAKICAjIHRoZW1lKGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAjICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfYmxhbmsoKSwKICAjICAgICAgIGF4aXMudGV4dC55ID0gZWxlbWVudF9ibGFuaygpLCAgIyBSZW1vdmUgeS1heGlzIHRleHQKICAjICAgICAgIGF4aXMudGlja3MueSA9IGVsZW1lbnRfYmxhbmsoKSkgKyAgIyBSZW1vdmUgeS1heGlzIHRpY2tzIAogIGdndGl0bGUoIkZlbWFsZXMiKQoKIyBDb21iaW5lIHRoZSB0d28gcGxvdHMgaW50byBvbmUgcGFuZWwgdXNpbmcgY293cGxvdApjb21iaW5lZF9wbG90X3NtYSA8LSBwbG90X2dyaWQocDFfbWFsZXNfc21hLCBwMl9mZW1hbGVzX3NtYSwgbmNvbCA9IDIpCgojIERpc3BsYXkgdGhlIGNvbWJpbmVkIHBsb3QKcHJpbnQoY29tYmluZWRfcGxvdF9zbWEpCgoKIyBTYXZlIHRoZSBwbG90cwpnZ3NhdmUocGFzdGUwKFBMT1RfbG9jLCAiLyIsIFRvZGF5LCAiLkRvdFBsb3QuVGFyZ2V0cy5Db2xvY0dyb3VwZWQuU01Bb25seS5HZW5kZXJNYWxlcy5wbmciKSwgcGxvdCA9IHAxX21hbGVzX3NtYSkKZ2dzYXZlKHBhc3RlMChQTE9UX2xvYywgIi8iLCBUb2RheSwgIi5Eb3RQbG90LlRhcmdldHMuQ29sb2NHcm91cGVkLlNNQW9ubHkuR2VuZGVyTWFsZXMucHMiKSwgcGxvdCA9IHAxX21hbGVzX3NtYSkKZ2dzYXZlKHBhc3RlMChQTE9UX2xvYywgIi8iLCBUb2RheSwgIi5Eb3RQbG90LlRhcmdldHMuQ29sb2NHcm91cGVkLlNNQW9ubHkuR2VuZGVyTWFsZXMucGRmIiksIHBsb3QgPSBwMV9tYWxlc19zbWEpCgpnZ3NhdmUocGFzdGUwKFBMT1RfbG9jLCAiLyIsIFRvZGF5LCAiLkRvdFBsb3QuVGFyZ2V0cy5Db2xvY0dyb3VwZWQuU01Bb25seS5HZW5kZXJGZW1hbGVzLnBuZyIpLCBwbG90ID0gcDJfZmVtYWxlc19zbWEpCmdnc2F2ZShwYXN0ZTAoUExPVF9sb2MsICIvIiwgVG9kYXksICIuRG90UGxvdC5UYXJnZXRzLkNvbG9jR3JvdXBlZC5TTUFvbmx5LkdlbmRlckZlbWFsZXMucHMiKSwgcGxvdCA9IHAyX2ZlbWFsZXNfc21hKQpnZ3NhdmUocGFzdGUwKFBMT1RfbG9jLCAiLyIsIFRvZGF5LCAiLkRvdFBsb3QuVGFyZ2V0cy5Db2xvY0dyb3VwZWQuU01Bb25seS5HZW5kZXJGZW1hbGVzLnBkZiIpLCBwbG90ID0gcDJfZmVtYWxlc19zbWEpCgpnZ3NhdmUocGFzdGUwKFBMT1RfbG9jLCAiLyIsIFRvZGF5LCAiLkRvdFBsb3QuVGFyZ2V0cy5Db2xvY0dyb3VwZWQuU01Bb25seS5HZW5kZXIucG5nIiksIHBsb3QgPSBjb21iaW5lZF9wbG90X3NtYSkKZ2dzYXZlKHBhc3RlMChQTE9UX2xvYywgIi8iLCBUb2RheSwgIi5Eb3RQbG90LlRhcmdldHMuQ29sb2NHcm91cGVkLlNNQW9ubHkuR2VuZGVyLnBzIiksIHBsb3QgPSBjb21iaW5lZF9wbG90X3NtYSkKZ2dzYXZlKHBhc3RlMChQTE9UX2xvYywgIi8iLCBUb2RheSwgIi5Eb3RQbG90LlRhcmdldHMuQ29sb2NHcm91cGVkLlNNQW9ubHkuR2VuZGVyLnBkZiIpLCBwbG90ID0gY29tYmluZWRfcGxvdF9zbWEpCgpgYGAKCmBgYHtyIFZpc3VhbGlzYXRpb246IFRhcmdldHMgRmVhdHVyZSBQbG90cywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KRmVhdHVyZVBsb3Qoc2NSTkFzZXFEYXRhQ0VBMzksIGZlYXR1cmVzID0gYyh0YXJnZXRfZ2VuZXNfcWMpLAogICAgICAgICAgICBjb2xzID0gIGMoIiNFQ0VDRUMiLCAiI0RCMDAzRiIsICIjOUEzNDgwIiwiIzEyOTBEOSIpLAogICAgICAgICAgICBjb21iaW5lID0gVFJVRSkKCmdnc2F2ZShwYXN0ZTAoUExPVF9sb2MsICIvIiwgVG9kYXksICIuRmVhdHVyZVBsb3QuVGFyZ2V0cy5wbmciKSwgcGxvdCA9IGxhc3RfcGxvdCgpKQpnZ3NhdmUocGFzdGUwKFBMT1RfbG9jLCAiLyIsIFRvZGF5LCAiLkZlYXR1cmVQbG90LlRhcmdldHMucHMiKSwgcGxvdCA9IGxhc3RfcGxvdCgpKQoKYGBgCgpgYGB7ciBWaXN1YWxpc2F0aW9uOiBUYXJnZXRzfQojIFZsblBsb3Qoc2NSTkFzZXFEYXRhQ0VBMzksIGZlYXR1cmVzID0gIkRVU1AyNyIpCgojIFZsblBsb3QgZmlsZXMKaWZlbHNlKCFkaXIuZXhpc3RzKGZpbGUucGF0aChQTE9UX2xvYywgIi9WbG5QbG90IikpLCAKICAgICAgIGRpci5jcmVhdGUoZmlsZS5wYXRoKFBMT1RfbG9jLCAiL1ZsblBsb3QiKSksIAogICAgICAgRkFMU0UpClZsblBsb3RfbG9jID0gcGFzdGUwKFBMT1RfbG9jLCAiL1ZsblBsb3QiKQoKCmZvciAoR0VORSBpbiB0YXJnZXRfZ2VuZXNfcWMpewogIHByaW50KHBhc3RlMCgiUHJvamVjdGluZyB0aGUgZXhwcmVzc2lvbiBvZiAiLCBHRU5FLCAiLiIpKQoKICB2cDEgPC0gIFZsblBsb3Qoc2NSTkFzZXFEYXRhQ0VBMzksIGZlYXR1cmVzID0gR0VORSkgKyAKICAgIHhsYWIoImNlbGwgY29tbXVuaXRpZXMiKSArIAogICAgeWxhYihicXVvdGUoIm5vcm1hbGl6ZWQgZXhwcmVzc2lvbiIpKSArCiAgICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoY29sb3IgPSAiIzAwMDAwMCIsIHNpemUgPSAxNCwgZmFjZSA9ICJib2xkIiksIAogICAgICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoY29sb3IgPSAiIzAwMDAwMCIsIHNpemUgPSAxNCwgZmFjZSA9ICJib2xkIiksIAogICAgICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCiAgICBnZ3NhdmUocGFzdGUwKFZsblBsb3RfbG9jLCAiLyIsIFRvZGF5LCAiLlZsblBsb3QuIixHRU5FLCIucG5nIiksIHBsb3QgPSBsYXN0X3Bsb3QoKSkKICAgIGdnc2F2ZShwYXN0ZTAoVmxuUGxvdF9sb2MsICIvIiwgVG9kYXksICIuVmxuUGxvdC4iLEdFTkUsIi5wcyIpLCBwbG90ID0gbGFzdF9wbG90KCkpCiAgICBnZ3NhdmUocGFzdGUwKFZsblBsb3RfbG9jLCAiLyIsIFRvZGF5LCAiLlZsblBsb3QuIixHRU5FLCIucGRmIiksIHBsb3QgPSBsYXN0X3Bsb3QoKSkKICAKICAjIHByaW50KHZwMSkKICAKfQoKYGBgCgojIyMgRGlmZmVyZW50aWFsIGV4cHJlc3Npb24gYmV0d2VlbiBjZWxsIGNvbW11bml0aWVzCgpIZXJlIHdlIHByb2plY3QgZ2VuZXMgdG8gb25seSB0aGUgYnJvYWQgY2VsbCBjb21tdW5pdGllczoKCi0gICBtYWNyb3BoYWdlcwotICAgZW5kb3RoZWxpYWwgY2VsbHMKLSAgIHNtb290aCBtdXNjbGUgY2VsbHMKLSAgIFQtY2VsbHMKLSAgIEItY2VsbHMKLSAgIE1hc3QgY2VsbHMKLSAgIE5LLWNlbGxzCi0gICBNaXhlZCBjZWxscwoKIyMjIyBNYWNyb3BoYWdlcwoKYGBge3J9CnVuaXF1ZShzY1JOQXNlcURhdGFDRUEzOUBhY3RpdmUuaWRlbnQpCmBgYAoKQ29tcGFyaXNvbiBiZXR3ZWVuIHRoZSBtYWNyb3BoYWdlcyBjZWxsIGNvbW11bml0aWVzICgqQ0QxNC9DRDY4KjxzdXA+Kzwvc3VwPiksCmFuZCBhbGwgb3RoZXIgY29tbXVuaXRpZXMuCgpgYGB7ciBWaXN1YWxpc2F0aW9uOiBWb2xjYW5vIE1BQyBjYWxjdWxhdGV9CgpNQUMubWFya2VycyA8LSBGaW5kTWFya2VycyhvYmplY3QgPSBzY1JOQXNlcURhdGFDRUEzOSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgaWRlbnQuMSA9IGMoIkNENjgrQ0FTUDErSUwxQitTRUxMIE1JbmYiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0Q2OCtDRDFDKyBEQyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDRDY4K0NENCsgTW9ubyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNENjgrSUwxOCtUTFI0K1RSRU0yKyBNUmVzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0Q2OCtBQkNBMStPTFIxK1RSRU0yKyBGQyIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICBpZGVudC4yID0gYygjIkNENjgrQ0FTUDErSUwxQitTRUxMIE1JbmYiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIkNENjgrQ0QxQysgREMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIkNENjgrQ0Q0KyBNb25vIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIkNENjgrSUwxOCtUTFI0K1RSRU0yKyBNUmVzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIkNENjgrQUJDQTErT0xSMStUUkVNMisgRkMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDRDMrIFRDIEkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDRDMrIFRDIElJIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNEMysgVEMgSUlJIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNEMysgVEMgSVYiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0QzKyBUQyBWIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNEMysgVEMgVkkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRk9YUDMrIFRDIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNEMzQrIEVDIEkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0QzNCsgRUMgSUkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBQ1RBMisgU01DIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNEMytDRDU2KyBOSyBJIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0QzK0NENTYrIE5LIElJIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNENjgrS0lUKyBNQyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNENzkrIEJDcGxhc21hIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNENzlBKyBCQ21lbSIpKQoKRFQ6OmRhdGF0YWJsZShNQUMubWFya2VycykKYGBgCgpgYGB7ciBWaXN1YWxpc2F0aW9uOiBWb2xjYW5vIE1BQywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KTUFDX1ZvbGNhbm9fVGFyZ2V0c0EgPSBFbmhhbmNlZFZvbGNhbm8oTUFDLm1hcmtlcnMsCiAgICBsYWIgPSByb3duYW1lcyhNQUMubWFya2VycyksCiAgICB4ID0gImF2Z19sb2cyRkMiLAogICAgeSA9ICJwX3ZhbF9hZGoiLAogICAgc2VsZWN0TGFiID0gdGFyZ2V0X2dlbmVzX3FjLAogICAgYXhpc0xhYlNpemUgPSAxMiwKICAgIHhsYWIgPSAiYXZlcmFnZSBmb2xkLWNoYW5nZSIsCiAgICB0aXRsZSA9ICJNYWNyb3BoYWdlIG1hcmtlcnNcbihNYWNyb3BoYWdlIGNvbW11bml0aWVzIHZzIHRoZSByZXN0KSIsCiAgICB0aXRsZUxhYlNpemUgPSAxNCwKICAgIHBDdXRvZmYgPSAwLjA1Lyhucm93KE1BQy5tYXJrZXJzKSksICMgMjA1NTIgZ2VuZXMKICAgIEZDY3V0b2ZmID0gMS4yNSwKICAgIHBvaW50U2l6ZSA9IDEuNSwKICAgIGxhYlNpemUgPSAzLjAsCiAgICBsZWdlbmRMYWJlbHMgPWMoJ05TJywnYXZnLiBmb2xkLWNoYW5nZScsJ1AnLAogICAgICAnUCAmIGF2Zy4gZm9sZC1jaGFuZ2UnKSwKICAgIGxlZ2VuZFBvc2l0aW9uID0gInJpZ2h0IiwKICAgIGxlZ2VuZExhYlNpemUgPSAxMCwKICAgIGxlZ2VuZEljb25TaXplID0gMy4wLAogICAgZHJhd0Nvbm5lY3RvcnMgPSBUUlVFLAogICAgd2lkdGhDb25uZWN0b3JzID0gMC4yLAogICAgY29sQ29ubmVjdG9ycyA9ICIjNTk1QTVDIiwKICAgIGdyaWRsaW5lcy5tYWpvciA9IEZBTFNFLAogICAgZ3JpZGxpbmVzLm1pbm9yID0gRkFMU0UpCk1BQ19Wb2xjYW5vX1RhcmdldHNBCmdnc2F2ZShwYXN0ZTAoUExPVF9sb2MsICIvIiwgVG9kYXksICIuVm9sY2Fuby5NQUMuREVHLlRhcmdldHMucGRmIiksIAogICAgICAgcGxvdCA9IE1BQ19Wb2xjYW5vX1RhcmdldHNBKQpgYGAKClRoZSB0YXJnZXQgcmVzdWx0cyBhcmUgZ2l2ZW4gYmVsb3cgYW5kIHdyaXR0ZW4gdG8gYSBmaWxlLgoKYGBge3IgUmVzdWx0cyBNQUN9CmxpYnJhcnkodGliYmxlKQpNQUMubWFya2VycyA8LSBhZGRfY29sdW1uKE1BQy5tYXJrZXJzLCBHZW5lID0gcm93Lm5hbWVzKE1BQy5tYXJrZXJzKSwgLmJlZm9yZSA9IDEpCgp0ZW1wIDwtIE1BQy5tYXJrZXJzW01BQy5tYXJrZXJzJEdlbmUgJWluJSB0YXJnZXRfZ2VuZXNfcWMsXQoKRFQ6OmRhdGF0YWJsZSh0ZW1wKQpgYGAKCmBgYHtyIFJlc3VsdHMgTUFDOiB3cml0aW5nfQpmd3JpdGUodGVtcCwgZmlsZSA9IHBhc3RlMChPVVRfbG9jLCAiLyIsIFRvZGF5LCAiLk1BQy5ERUcuVGFyZ2V0cy50eHQiKSwKICAgICAgIHF1b3RlID0gRkFMU0UsCiAgICAgICBzZXAgPSAiXHQiLCAKICAgICAgIHNob3dQcm9ncmVzcyA9IEZBTFNFLCB2ZXJib3NlID0gRkFMU0UpCmBgYAoKIyMjIyBTbW9vdGggbXVzY2xlIGNlbGxzCgpDb21wYXJpc29uIGJldHdlZW4gdGhlIHNtb290aCBtdXNjbGUgY2VsbCBjb21tdW5pdGllcyAoKkFDVEEyKjxzdXA+Kzwvc3VwPiksIGFuZAphbGwgb3RoZXIgY29tbXVuaXRpZXMuCgpgYGB7ciBWaXN1YWxpc2F0aW9uOiBWb2xjYW5vIFNNQyBjYWxjdWxhdGV9CgpTTUMubWFya2VycyA8LSBGaW5kTWFya2VycyhvYmplY3QgPSBzY1JOQXNlcURhdGFDRUEzOSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgaWRlbnQuMSA9IGMoIkFDVEEyKyBTTUMiKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgaWRlbnQuMiA9IGMoIkNENjgrQ0FTUDErSUwxQitTRUxMIE1JbmYiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0Q2OCtDRDFDKyBEQyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDRDY4K0NENCsgTW9ubyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNENjgrSUwxOCtUTFI0K1RSRU0yKyBNUmVzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0Q2OCtBQkNBMStPTFIxK1RSRU0yKyBGQyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNEMysgVEMgSSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNEMysgVEMgSUkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0QzKyBUQyBJSUkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0QzKyBUQyBJViIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDRDMrIFRDIFYiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0QzKyBUQyBWSSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGT1hQMysgVEMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0QzNCsgRUMgSSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDRDM0KyBFQyBJSSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyJBQ1RBMisgU01DIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNEMytDRDU2KyBOSyBJIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0QzK0NENTYrIE5LIElJIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNENjgrS0lUKyBNQyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNENzkrIEJDcGxhc21hIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNENzlBKyBCQ21lbSIpKQoKRFQ6OmRhdGF0YWJsZShTTUMubWFya2VycykKYGBgCgpgYGB7ciBWaXN1YWxpc2F0aW9uOiBWb2xjYW5vIFNNQywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KU01DX1ZvbGNhbm9fVGFyZ2V0c0EgPSBFbmhhbmNlZFZvbGNhbm8oU01DLm1hcmtlcnMsCiAgICBsYWIgPSByb3duYW1lcyhTTUMubWFya2VycyksCiAgICB4ID0gImF2Z19sb2cyRkMiLAogICAgeSA9ICJwX3ZhbF9hZGoiLAogICAgc2VsZWN0TGFiID0gdGFyZ2V0X2dlbmVzX3FjLAogICAgYXhpc0xhYlNpemUgPSAxMiwKICAgIHhsYWIgPSAiYXZlcmFnZSBmb2xkLWNoYW5nZSIsCiAgICB0aXRsZSA9ICJTTUMgbWFya2Vyc1xuKFNNQyBjb21tdW5pdGllcyB2cyB0aGUgcmVzdCkiLAogICAgdGl0bGVMYWJTaXplID0gMTQsCiAgICBwQ3V0b2ZmID0gMC4wNS8obnJvdyhTTUMubWFya2VycykpLCAjIDIwNTUyIGdlbmVzCiAgICBGQ2N1dG9mZiA9IDEuMjUsCiAgICBwb2ludFNpemUgPSAxLjUsCiAgICBsYWJTaXplID0gMy4wLAogICAgbGVnZW5kTGFiZWxzID1jKCdOUycsJ2F2Zy4gZm9sZC1jaGFuZ2UnLCdQJywKICAgICAgJ1AgJiBhdmcuIGZvbGQtY2hhbmdlJyksCiAgICBsZWdlbmRQb3NpdGlvbiA9ICJyaWdodCIsCiAgICBsZWdlbmRMYWJTaXplID0gMTAsCiAgICBsZWdlbmRJY29uU2l6ZSA9IDMuMCwKICAgIGRyYXdDb25uZWN0b3JzID0gVFJVRSwKICAgIHdpZHRoQ29ubmVjdG9ycyA9IDAuMiwKICAgIGNvbENvbm5lY3RvcnMgPSAiIzU5NUE1QyIsCiAgICBncmlkbGluZXMubWFqb3IgPSBGQUxTRSwKICAgIGdyaWRsaW5lcy5taW5vciA9IEZBTFNFKQpTTUNfVm9sY2Fub19UYXJnZXRzQQpnZ3NhdmUocGFzdGUwKFBMT1RfbG9jLCAiLyIsIFRvZGF5LCAiLlZvbGNhbm8uU01DLkRFRy5UYXJnZXRzLnBkZiIpLCAKICAgICAgIHBsb3QgPSBTTUNfVm9sY2Fub19UYXJnZXRzQSkKYGBgCgpUaGUgdGFyZ2V0IHJlc3VsdHMgYXJlIGdpdmVuIGJlbG93IGFuZCB3cml0dGVuIHRvIGEgZmlsZS4KCmBgYHtyIFJlc3VsdHMgU01DfQpsaWJyYXJ5KHRpYmJsZSkKU01DLm1hcmtlcnMgPC0gYWRkX2NvbHVtbihTTUMubWFya2VycywgR2VuZSA9IHJvdy5uYW1lcyhTTUMubWFya2VycyksIC5iZWZvcmUgPSAxKQoKdGVtcCA8LSBTTUMubWFya2Vyc1tTTUMubWFya2VycyRHZW5lICVpbiUgdGFyZ2V0X2dlbmVzX3FjLF0KCkRUOjpkYXRhdGFibGUodGVtcCkKYGBgCgpgYGB7ciBSZXN1bHRzIFNNQzogd3JpdGluZ30KZndyaXRlKHRlbXAsIGZpbGUgPSBwYXN0ZTAoT1VUX2xvYywgIi8iLCBUb2RheSwgIi5TTUMuREVHLlRhcmdldHMudHh0IiksCiAgICAgICBxdW90ZSA9IEZBTFNFLAogICAgICAgc2VwID0gIlx0IiwgCiAgICAgICBzaG93UHJvZ3Jlc3MgPSBGQUxTRSwgdmVyYm9zZSA9IEZBTFNFKQpgYGAKCiMjIyMgRW5kb3RoZWxpYWwgY2VsbHMKCkNvbXBhcmlzb24gYmV0d2VlbiB0aGUgZW5kb3RoZWxpYWwgY2VsbCBjb21tdW5pdGllcyAoKkNEMzQqPHN1cD4rPC9zdXA+KSwgYW5kCmFsbCBvdGhlciBjb21tdW5pdGllcy4KCmBgYHtyIFZpc3VhbGlzYXRpb246IFZvbGNhbm8gRUMgY2FsY3VsYXRlfQoKRUMubWFya2VycyA8LSBGaW5kTWFya2VycyhvYmplY3QgPSBzY1JOQXNlcURhdGFDRUEzOSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgaWRlbnQuMSA9IGMoIkNEMzQrIEVDIEkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0QzNCsgRUMgSUkiKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgaWRlbnQuMiA9IGMoIkNENjgrQ0FTUDErSUwxQitTRUxMIE1JbmYiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0Q2OCtDRDFDKyBEQyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDRDY4K0NENCsgTW9ubyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNENjgrSUwxOCtUTFI0K1RSRU0yKyBNUmVzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0Q2OCtBQkNBMStPTFIxK1RSRU0yKyBGQyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNEMysgVEMgSSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNEMysgVEMgSUkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0QzKyBUQyBJSUkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0QzKyBUQyBJViIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDRDMrIFRDIFYiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0QzKyBUQyBWSSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGT1hQMysgVEMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjICJDRDM0KyBFQyBJIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyAiQ0QzNCsgRUMgSUkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBQ1RBMisgU01DIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNEMytDRDU2KyBOSyBJIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0QzK0NENTYrIE5LIElJIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNENjgrS0lUKyBNQyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNENzkrIEJDcGxhc21hIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNENzlBKyBCQ21lbSIpKQoKRFQ6OmRhdGF0YWJsZShFQy5tYXJrZXJzKQpgYGAKCmBgYHtyIFZpc3VhbGlzYXRpb246IFZvbGNhbm8gRUMsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CkVDX1ZvbGNhbm9fVGFyZ2V0c0EgPSBFbmhhbmNlZFZvbGNhbm8oRUMubWFya2VycywKICAgIGxhYiA9IHJvd25hbWVzKEVDLm1hcmtlcnMpLAogICAgeCA9ICJhdmdfbG9nMkZDIiwKICAgIHkgPSAicF92YWxfYWRqIiwKICAgIHNlbGVjdExhYiA9IHRhcmdldF9nZW5lc19xYywKICAgIGF4aXNMYWJTaXplID0gMTIsCiAgICB4bGFiID0gImF2ZXJhZ2UgZm9sZC1jaGFuZ2UiLAogICAgdGl0bGUgPSAiRW5kb3RoZWxpYWwgY2VsbCBtYXJrZXJzXG4oRUMgY29tbXVuaXRpZXMgdnMgdGhlIHJlc3QpIiwKICAgIHRpdGxlTGFiU2l6ZSA9IDE0LAogICAgcEN1dG9mZiA9IDAuMDUvKG5yb3coRUMubWFya2VycykpLCAjIDIwNTUyIGdlbmVzCiAgICBGQ2N1dG9mZiA9IDEuMjUsCiAgICBwb2ludFNpemUgPSAxLjUsCiAgICBsYWJTaXplID0gMy4wLAogICAgbGVnZW5kTGFiZWxzID1jKCdOUycsJ2F2Zy4gZm9sZC1jaGFuZ2UnLCdQJywKICAgICAgJ1AgJiBhdmcuIGZvbGQtY2hhbmdlJyksCiAgICBsZWdlbmRQb3NpdGlvbiA9ICJyaWdodCIsCiAgICBsZWdlbmRMYWJTaXplID0gMTAsCiAgICBsZWdlbmRJY29uU2l6ZSA9IDMuMCwKICAgIGRyYXdDb25uZWN0b3JzID0gVFJVRSwKICAgIHdpZHRoQ29ubmVjdG9ycyA9IDAuMiwKICAgIGNvbENvbm5lY3RvcnMgPSAiIzU5NUE1QyIsCiAgICBncmlkbGluZXMubWFqb3IgPSBGQUxTRSwKICAgIGdyaWRsaW5lcy5taW5vciA9IEZBTFNFKQpFQ19Wb2xjYW5vX1RhcmdldHNBCmdnc2F2ZShwYXN0ZTAoUExPVF9sb2MsICIvIiwgVG9kYXksICIuVm9sY2Fuby5FQy5ERUcuVGFyZ2V0cy5wZGYiKSwgCiAgICAgICBwbG90ID0gRUNfVm9sY2Fub19UYXJnZXRzQSkKYGBgCgpUaGUgdGFyZ2V0IHJlc3VsdHMgYXJlIGdpdmVuIGJlbG93IGFuZCB3cml0dGVuIHRvIGEgZmlsZS4KCmBgYHtyIFJlc3VsdHMgRUN9CmxpYnJhcnkodGliYmxlKQpFQy5tYXJrZXJzIDwtIGFkZF9jb2x1bW4oRUMubWFya2VycywgR2VuZSA9IHJvdy5uYW1lcyhFQy5tYXJrZXJzKSwgLmJlZm9yZSA9IDEpCgp0ZW1wIDwtIEVDLm1hcmtlcnNbRUMubWFya2VycyRHZW5lICVpbiUgdGFyZ2V0X2dlbmVzX3FjLF0KCkRUOjpkYXRhdGFibGUodGVtcCkKYGBgCgpgYGB7ciBSZXN1bHRzIEVDOiB3cml0aW5nfQpmd3JpdGUodGVtcCwgZmlsZSA9IHBhc3RlMChPVVRfbG9jLCAiLyIsIFRvZGF5LCAiLkVDLkRFRy5UYXJnZXRzLnR4dCIpLAogICAgICAgcXVvdGUgPSBGQUxTRSwKICAgICAgIHNlcCA9ICJcdCIsIAogICAgICAgc2hvd1Byb2dyZXNzID0gRkFMU0UsIHZlcmJvc2UgPSBGQUxTRSkKYGBgCgojIyMjIFQtY2VsbHMKCkNvbXBhcmlzb24gYmV0d2VlbiB0aGUgVC1jZWxsIGNvbW11bml0aWVzICgqQ0QzL0NENC9DRDgqPHN1cD4rPC9zdXA+KSwgYW5kIGFsbApvdGhlciBjb21tdW5pdGllcy4KCmBgYHtyIFZpc3VhbGlzYXRpb246IFZvbGNhbm8gVGNlbGwgY2FsY3VsYXRlfQoKVEMubWFya2VycyA8LSBGaW5kTWFya2VycyhvYmplY3QgPSBzY1JOQXNlcURhdGFDRUEzOSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgaWRlbnQuMSA9IGMoIkNEMysgVEMgSSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNEMysgVEMgSUkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0QzKyBUQyBJSUkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0QzKyBUQyBJViIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDRDMrIFRDIFYiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0QzKyBUQyBWSSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGT1hQMysgVEMiKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgaWRlbnQuMiA9IGMoIkNENjgrQ0FTUDErSUwxQitTRUxMIE1JbmYiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0Q2OCtDRDFDKyBEQyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDRDY4K0NENCsgTW9ubyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNENjgrSUwxOCtUTFI0K1RSRU0yKyBNUmVzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0Q2OCtBQkNBMStPTFIxK1RSRU0yKyBGQyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyAiQ0QzKyBUQyBJIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjICJDRDMrIFRDIElJIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyAiQ0QzKyBUQyBJSUkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjICJDRDMrIFRDIElWIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyAiQ0QzKyBUQyBWIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyAiQ0QzKyBUQyBWSSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgIkZPWFAzKyBUQyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDRDM0KyBFQyBJIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNEMzQrIEVDIElJIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQUNUQTIrIFNNQyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDRDMrQ0Q1NisgTksgSSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNEMytDRDU2KyBOSyBJSSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDRDY4K0tJVCsgTUMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDRDc5KyBCQ3BsYXNtYSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDRDc5QSsgQkNtZW0iKSkKCkRUOjpkYXRhdGFibGUoVEMubWFya2VycykKYGBgCgpgYGB7ciBWaXN1YWxpc2F0aW9uOiBWb2xjYW5vIFRjZWxsLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpUQ19Wb2xjYW5vX1RhcmdldHNBID0gRW5oYW5jZWRWb2xjYW5vKFRDLm1hcmtlcnMsCiAgICBsYWIgPSByb3duYW1lcyhUQy5tYXJrZXJzKSwKICAgIHggPSAiYXZnX2xvZzJGQyIsCiAgICB5ID0gInBfdmFsX2FkaiIsCiAgICBzZWxlY3RMYWIgPSB0YXJnZXRfZ2VuZXNfcWMsCiAgICBheGlzTGFiU2l6ZSA9IDEyLAogICAgeGxhYiA9ICJhdmVyYWdlIGZvbGQtY2hhbmdlIiwKICAgIHRpdGxlID0gIlQtY2VsbCBtYXJrZXJzXG4oVC1jZWxsIGNvbW11bml0aWVzIHZzIHRoZSByZXN0KSIsCiAgICB0aXRsZUxhYlNpemUgPSAxNCwKICAgIHBDdXRvZmYgPSAwLjA1L25yb3coVEMubWFya2VycyksICMgMjA1NTIgZ2VuZXMKICAgIEZDY3V0b2ZmID0gMS4yNSwKICAgIHBvaW50U2l6ZSA9IDEuNSwKICAgIGxhYlNpemUgPSAzLjAsCiAgICBsZWdlbmRMYWJlbHMgPWMoJ05TJywnYXZnLiBmb2xkLWNoYW5nZScsJ1AnLAogICAgICAnUCAmIGF2Zy4gZm9sZC1jaGFuZ2UnKSwKICAgIGxlZ2VuZFBvc2l0aW9uID0gInJpZ2h0IiwKICAgIGxlZ2VuZExhYlNpemUgPSAxMCwKICAgIGxlZ2VuZEljb25TaXplID0gMy4wLAogICAgZHJhd0Nvbm5lY3RvcnMgPSBUUlVFLAogICAgd2lkdGhDb25uZWN0b3JzID0gMC4yLAogICAgY29sQ29ubmVjdG9ycyA9ICIjNTk1QTVDIiwKICAgIGdyaWRsaW5lcy5tYWpvciA9IEZBTFNFLAogICAgZ3JpZGxpbmVzLm1pbm9yID0gRkFMU0UpClRDX1ZvbGNhbm9fVGFyZ2V0c0EKZ2dzYXZlKHBhc3RlMChQTE9UX2xvYywgIi8iLCBUb2RheSwgIi5Wb2xjYW5vLlRDLkRFRy5UYXJnZXRzLnBkZiIpLCAKICAgICAgIHBsb3QgPSBUQ19Wb2xjYW5vX1RhcmdldHNBKQpgYGAKClRoZSB0YXJnZXQgcmVzdWx0cyBhcmUgZ2l2ZW4gYmVsb3cgYW5kIHdyaXR0ZW4gdG8gYSBmaWxlLgoKYGBge3IgUmVzdWx0cyBUQ30KbGlicmFyeSh0aWJibGUpClRDLm1hcmtlcnMgPC0gYWRkX2NvbHVtbihUQy5tYXJrZXJzLCBHZW5lID0gcm93Lm5hbWVzKFRDLm1hcmtlcnMpLCAuYmVmb3JlID0gMSkKCnRlbXAgPC0gVEMubWFya2Vyc1tUQy5tYXJrZXJzJEdlbmUgJWluJSB0YXJnZXRfZ2VuZXNfcWMsXQoKRFQ6OmRhdGF0YWJsZSh0ZW1wKQpgYGAKCmBgYHtyIFJlc3VsdHMgVEM6IHdyaXRpbmd9CmZ3cml0ZSh0ZW1wLCBmaWxlID0gcGFzdGUwKE9VVF9sb2MsICIvIiwgVG9kYXksICIuVEMuREVHLlRhcmdldHMudHh0IiksCiAgICAgICBxdW90ZSA9IEZBTFNFLAogICAgICAgc2VwID0gIlx0IiwgCiAgICAgICBzaG93UHJvZ3Jlc3MgPSBGQUxTRSwgdmVyYm9zZSA9IEZBTFNFKQpgYGAKCiMjIyMgQi1jZWxscwoKQ29tcGFyaXNvbiBiZXR3ZWVuIHRoZSBCLWNlbGwgY29tbXVuaXRpZXMgKCpDRDc5QSo8c3VwPis8L3N1cD4pLCBhbmQgYWxsIG90aGVyCmNvbW11bml0aWVzLgoKYGBge3IgVmlzdWFsaXNhdGlvbjogVm9sY2FubyBCY2VsbCBjYWxjdWxhdGV9CgpCQy5tYXJrZXJzIDwtIEZpbmRNYXJrZXJzKG9iamVjdCA9IHNjUk5Bc2VxRGF0YUNFQTM5LCAKICAgICAgICAgICAgICAgICAgICAgICAgICBpZGVudC4xID0gYygiQ0Q3OSsgQkNwbGFzbWEiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0Q3OUErIEJDbWVtIiksIAogICAgICAgICAgICAgICAgICAgICAgICAgIGlkZW50LjIgPSBjKCJDRDY4K0NBU1AxK0lMMUIrU0VMTCBNSW5mIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNENjgrQ0QxQysgREMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0Q2OCtDRDQrIE1vbm8iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDRDY4K0lMMTgrVExSNCtUUkVNMisgTVJlcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNENjgrQUJDQTErT0xSMStUUkVNMisgRkMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDRDMrIFRDIEkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDRDMrIFRDIElJIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNEMysgVEMgSUlJIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNEMysgVEMgSVYiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0QzKyBUQyBWIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNEMysgVEMgVkkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRk9YUDMrIFRDIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNEMzQrIEVDIEkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0QzNCsgRUMgSUkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBQ1RBMisgU01DIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNEMytDRDU2KyBOSyBJIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0QzK0NENTYrIE5LIElJIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNENjgrS0lUKyBNQyIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjICJDRDc5KyBCQ3BsYXNtYSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgIkNENzlBKyBCQ21lbSIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApKQoKRFQ6OmRhdGF0YWJsZShCQy5tYXJrZXJzKQpgYGAKCmBgYHtyIFZpc3VhbGlzYXRpb246IFZvbGNhbm8gQmNlbGwsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CkJDX1ZvbGNhbm9fVGFyZ2V0c0EgPSBFbmhhbmNlZFZvbGNhbm8oQkMubWFya2VycywKICAgIGxhYiA9IHJvd25hbWVzKEJDLm1hcmtlcnMpLAogICAgeCA9ICJhdmdfbG9nMkZDIiwKICAgIHkgPSAicF92YWxfYWRqIiwKICAgIHNlbGVjdExhYiA9IHRhcmdldF9nZW5lc19xYywKICAgIGF4aXNMYWJTaXplID0gMTIsCiAgICB4bGFiID0gImF2ZXJhZ2UgZm9sZC1jaGFuZ2UiLAogICAgdGl0bGUgPSAiQi1jZWxsIG1hcmtlcnNcbihCLWNlbGwgY29tbXVuaXRpZXMgdnMgdGhlIHJlc3QpIiwKICAgIHRpdGxlTGFiU2l6ZSA9IDE0LAogICAgcEN1dG9mZiA9IDAuMDUvbnJvdyhCQy5tYXJrZXJzKSwgIyAyMDU1MiBnZW5lcwogICAgRkNjdXRvZmYgPSAxLjI1LAogICAgcG9pbnRTaXplID0gMS41LAogICAgbGFiU2l6ZSA9IDMuMCwKICAgIGxlZ2VuZExhYmVscyA9YygnTlMnLCdhdmcuIGZvbGQtY2hhbmdlJywnUCcsCiAgICAgICdQICYgYXZnLiBmb2xkLWNoYW5nZScpLAogICAgbGVnZW5kUG9zaXRpb24gPSAicmlnaHQiLAogICAgbGVnZW5kTGFiU2l6ZSA9IDEwLAogICAgbGVnZW5kSWNvblNpemUgPSAzLjAsCiAgICBkcmF3Q29ubmVjdG9ycyA9IFRSVUUsCiAgICB3aWR0aENvbm5lY3RvcnMgPSAwLjIsCiAgICBjb2xDb25uZWN0b3JzID0gIiM1OTVBNUMiLAogICAgZ3JpZGxpbmVzLm1ham9yID0gRkFMU0UsCiAgICBncmlkbGluZXMubWlub3IgPSBGQUxTRSkKQkNfVm9sY2Fub19UYXJnZXRzQQpnZ3NhdmUocGFzdGUwKFBMT1RfbG9jLCAiLyIsIFRvZGF5LCAiLlZvbGNhbm8uQkMuREVHLlRhcmdldHMucGRmIiksIAogICAgICAgcGxvdCA9IEJDX1ZvbGNhbm9fVGFyZ2V0c0EpCmBgYAoKVGhlIHRhcmdldCByZXN1bHRzIGFyZSBnaXZlbiBiZWxvdyBhbmQgd3JpdHRlbiB0byBhIGZpbGUuCgpgYGB7ciBSZXN1bHRzIEJDfQpsaWJyYXJ5KHRpYmJsZSkKQkMubWFya2VycyA8LSBhZGRfY29sdW1uKEJDLm1hcmtlcnMsIEdlbmUgPSByb3cubmFtZXMoQkMubWFya2VycyksIC5iZWZvcmUgPSAxKQoKdGVtcCA8LSBCQy5tYXJrZXJzW0JDLm1hcmtlcnMkR2VuZSAlaW4lIHRhcmdldF9nZW5lc19xYyxdCgpEVDo6ZGF0YXRhYmxlKHRlbXApCmBgYAoKYGBge3IgUmVzdWx0cyBCQzogd3JpdGluZ30KZndyaXRlKHRlbXAsIGZpbGUgPSBwYXN0ZTAoT1VUX2xvYywgIi8iLCBUb2RheSwgIi5CQy5ERUcuVGFyZ2V0cy50eHQiKSwKICAgICAgIHF1b3RlID0gRkFMU0UsCiAgICAgICBzZXAgPSAiXHQiLCAKICAgICAgIHNob3dQcm9ncmVzcyA9IEZBTFNFLCB2ZXJib3NlID0gRkFMU0UpCmBgYAoKIyMjIyBNYXN0IGNlbGxzCgpDb21wYXJpc29uIGJldHdlZW4gdGhlIG1hc3QgY2VsbCBjb21tdW5pdGllcyAoKktJVCo8c3VwPis8L3N1cD4pLCBhbmQgYWxsIG90aGVyCmNvbW11bml0aWVzLgoKYGBge3IgVmlzdWFsaXNhdGlvbjogVm9sY2FubyBNYXN0IGNhbGN1bGF0ZX0KCk1DLm1hcmtlcnMgPC0gRmluZE1hcmtlcnMob2JqZWN0ID0gc2NSTkFzZXFEYXRhQ0VBMzksIAogICAgICAgICAgICAgICAgICAgICAgICAgIGlkZW50LjEgPSBjKCJDRDY4K0tJVCsgTUMiKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgaWRlbnQuMiA9IGMoIkNENjgrQ0FTUDErSUwxQitTRUxMIE1JbmYiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0Q2OCtDRDFDKyBEQyIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDRDY4K0NENCsgTW9ubyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNENjgrSUwxOCtUTFI0K1RSRU0yKyBNUmVzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0Q2OCtBQkNBMStPTFIxK1RSRU0yKyBGQyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNEMysgVEMgSSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNEMysgVEMgSUkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0QzKyBUQyBJSUkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0QzKyBUQyBJViIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDRDMrIFRDIFYiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0QzKyBUQyBWSSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGT1hQMysgVEMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0QzNCsgRUMgSSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDRDM0KyBFQyBJSSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFDVEEyKyBTTUMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0QzK0NENTYrIE5LIEkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDRDMrQ0Q1NisgTksgSUkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjICJDRDY4K0tJVCsgTUMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDRDc5KyBCQ3BsYXNtYSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDRDc5QSsgQkNtZW0iKSkKCkRUOjpkYXRhdGFibGUoTUMubWFya2VycykKYGBgCgpgYGB7ciBWaXN1YWxpc2F0aW9uOiBWb2xjYW5vIE1hc3QsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9Ck1DX1ZvbGNhbm9fVGFyZ2V0c0EgPSBFbmhhbmNlZFZvbGNhbm8oTUMubWFya2VycywKICAgIGxhYiA9IHJvd25hbWVzKE1DLm1hcmtlcnMpLAogICAgeCA9ICJhdmdfbG9nMkZDIiwKICAgIHkgPSAicF92YWxfYWRqIiwKICAgIHNlbGVjdExhYiA9IHRhcmdldF9nZW5lc19xYywKICAgIGF4aXNMYWJTaXplID0gMTIsCiAgICB4bGFiID0gImF2ZXJhZ2UgZm9sZC1jaGFuZ2UiLAogICAgdGl0bGUgPSAiTWFzdCBjZWxsIG1hcmtlcnNcbihNYXN0IGNlbGwgY29tbXVuaXRpZXMgdnMgdGhlIHJlc3QpIiwKICAgIHRpdGxlTGFiU2l6ZSA9IDE0LAogICAgcEN1dG9mZiA9IDAuMDUvbnJvdyhNQy5tYXJrZXJzKSwgIyAyMDU1MiBnZW5lcwogICAgRkNjdXRvZmYgPSAxLjI1LAogICAgcG9pbnRTaXplID0gMS41LAogICAgbGFiU2l6ZSA9IDMuMCwKICAgIGxlZ2VuZExhYmVscyA9YygnTlMnLCdhdmcuIGZvbGQtY2hhbmdlJywnUCcsCiAgICAgICdQICYgYXZnLiBmb2xkLWNoYW5nZScpLAogICAgbGVnZW5kUG9zaXRpb24gPSAicmlnaHQiLAogICAgbGVnZW5kTGFiU2l6ZSA9IDEwLAogICAgbGVnZW5kSWNvblNpemUgPSAzLjAsCiAgICBkcmF3Q29ubmVjdG9ycyA9IFRSVUUsCiAgICB3aWR0aENvbm5lY3RvcnMgPSAwLjIsCiAgICBjb2xDb25uZWN0b3JzID0gIiM1OTVBNUMiLAogICAgZ3JpZGxpbmVzLm1ham9yID0gRkFMU0UsCiAgICBncmlkbGluZXMubWlub3IgPSBGQUxTRSkKTUNfVm9sY2Fub19UYXJnZXRzQQpnZ3NhdmUocGFzdGUwKFBMT1RfbG9jLCAiLyIsIFRvZGF5LCAiLlZvbGNhbm8uTUMuREVHLlRhcmdldHMucGRmIiksIAogICAgICAgcGxvdCA9IE1DX1ZvbGNhbm9fVGFyZ2V0c0EpCmBgYAoKVGhlIHRhcmdldCByZXN1bHRzIGFyZSBnaXZlbiBiZWxvdyBhbmQgd3JpdHRlbiB0byBhIGZpbGUuCgpgYGB7ciBSZXN1bHRzIE1DfQpsaWJyYXJ5KHRpYmJsZSkKTUMubWFya2VycyA8LSBhZGRfY29sdW1uKE1DLm1hcmtlcnMsIEdlbmUgPSByb3cubmFtZXMoTUMubWFya2VycyksIC5iZWZvcmUgPSAxKQoKdGVtcCA8LSBNQy5tYXJrZXJzW01DLm1hcmtlcnMkR2VuZSAlaW4lIHRhcmdldF9nZW5lc19xYyxdCgpEVDo6ZGF0YXRhYmxlKHRlbXApCmBgYAoKYGBge3IgUmVzdWx0cyBNQzogd3JpdGluZ30KZndyaXRlKHRlbXAsIGZpbGUgPSBwYXN0ZTAoT1VUX2xvYywgIi8iLCBUb2RheSwgIi5NQy5ERUcuVGFyZ2V0cy50eHQiKSwKICAgICAgIHF1b3RlID0gRkFMU0UsCiAgICAgICBzZXAgPSAiXHQiLCAKICAgICAgIHNob3dQcm9ncmVzcyA9IEZBTFNFLCB2ZXJib3NlID0gRkFMU0UpCmBgYAoKIyMjIyBOSy1jZWxscwoKQ29tcGFyaXNvbiBiZXR3ZWVuIHRoZSBuYXR1cmFsIGtpbGxlciBjZWxsIGNvbW11bml0aWVzICgqTkNBTTEqPHN1cD4rPC9zdXA+KSwKYW5kIGFsbCBvdGhlciBjb21tdW5pdGllcy4KCmBgYHtyIFZpc3VhbGlzYXRpb246IFZvbGNhbm8gTksgY2FsY3VsYXRlfQoKTksubWFya2VycyA8LSBGaW5kTWFya2VycyhvYmplY3QgPSBzY1JOQXNlcURhdGFDRUEzOSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgaWRlbnQuMSA9IGMoIkNEMytDRDU2KyBOSyBJIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0QzK0NENTYrIE5LIElJIiksIAogICAgICAgICAgICAgICAgICAgICAgICAgIGlkZW50LjIgPSBjKCJDRDY4K0NBU1AxK0lMMUIrU0VMTCBNSW5mIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNENjgrQ0QxQysgREMiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0Q2OCtDRDQrIE1vbm8iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDRDY4K0lMMTgrVExSNCtUUkVNMisgTVJlcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNENjgrQUJDQTErT0xSMStUUkVNMisgRkMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDRDMrIFRDIEkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDRDMrIFRDIElJIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNEMysgVEMgSUlJIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNEMysgVEMgSVYiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0QzKyBUQyBWIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNEMysgVEMgVkkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRk9YUDMrIFRDIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNEMzQrIEVDIEkiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQ0QzNCsgRUMgSUkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJBQ1RBMisgU01DIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyAiQ0QzK0NENTYrIE5LIEkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgIkNEMytDRDU2KyBOSyBJSSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDRDY4K0tJVCsgTUMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDRDc5KyBCQ3BsYXNtYSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDRDc5QSsgQkNtZW0iKSkKCkRUOjpkYXRhdGFibGUoTksubWFya2VycykKYGBgCgpgYGB7ciBWaXN1YWxpc2F0aW9uOiBWb2xjYW5vIE5LLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpOS19Wb2xjYW5vX1RhcmdldHNBID0gRW5oYW5jZWRWb2xjYW5vKE5LLm1hcmtlcnMsCiAgICBsYWIgPSByb3duYW1lcyhOSy5tYXJrZXJzKSwKICAgIHggPSAiYXZnX2xvZzJGQyIsCiAgICB5ID0gInBfdmFsX2FkaiIsCiAgICBzZWxlY3RMYWIgPSB0YXJnZXRfZ2VuZXNfcWMsCiAgICBheGlzTGFiU2l6ZSA9IDEyLAogICAgeGxhYiA9ICJhdmVyYWdlIGZvbGQtY2hhbmdlIiwKICAgIHRpdGxlID0gIk5LIG1hcmtlcnNcbihOSy1jZWxsIGNvbW11bml0aWVzIHZzIHRoZSByZXN0KSIsCiAgICB0aXRsZUxhYlNpemUgPSAxNCwKICAgIHBDdXRvZmYgPSAwLjA1L25yb3coTksubWFya2VycyksICMgMjA1NTIgZ2VuZXMKICAgIEZDY3V0b2ZmID0gMS4yNSwKICAgIHBvaW50U2l6ZSA9IDEuNSwKICAgIGxhYlNpemUgPSAzLjAsCiAgICBsZWdlbmRMYWJlbHMgPWMoJ05TJywnYXZnLiBmb2xkLWNoYW5nZScsJ1AnLAogICAgICAnUCAmIGF2Zy4gZm9sZC1jaGFuZ2UnKSwKICAgIGxlZ2VuZFBvc2l0aW9uID0gInJpZ2h0IiwKICAgIGxlZ2VuZExhYlNpemUgPSAxMCwKICAgIGxlZ2VuZEljb25TaXplID0gMy4wLAogICAgZHJhd0Nvbm5lY3RvcnMgPSBUUlVFLAogICAgd2lkdGhDb25uZWN0b3JzID0gMC4yLAogICAgY29sQ29ubmVjdG9ycyA9ICIjNTk1QTVDIiwKICAgIGdyaWRsaW5lcy5tYWpvciA9IEZBTFNFLAogICAgZ3JpZGxpbmVzLm1pbm9yID0gRkFMU0UpCk5LX1ZvbGNhbm9fVGFyZ2V0c0EKZ2dzYXZlKHBhc3RlMChQTE9UX2xvYywgIi8iLCBUb2RheSwgIi5Wb2xjYW5vLk5LLkRFRy5UYXJnZXRzLnBkZiIpLCAKICAgICAgIHBsb3QgPSBOS19Wb2xjYW5vX1RhcmdldHNBKQpgYGAKClRoZSB0YXJnZXQgcmVzdWx0cyBhcmUgZ2l2ZW4gYmVsb3cgYW5kIHdyaXR0ZW4gdG8gYSBmaWxlLgoKYGBge3IgUmVzdWx0cyBOS30KbGlicmFyeSh0aWJibGUpCk5LLm1hcmtlcnMgPC0gYWRkX2NvbHVtbihOSy5tYXJrZXJzLCBHZW5lID0gcm93Lm5hbWVzKE5LLm1hcmtlcnMpLCAuYmVmb3JlID0gMSkKCnRlbXAgPC0gTksubWFya2Vyc1tOSy5tYXJrZXJzJEdlbmUgJWluJSB0YXJnZXRfZ2VuZXNfcWMsXQoKRFQ6OmRhdGF0YWJsZSh0ZW1wKQpgYGAKCmBgYHtyIFJlc3VsdHMgTks6IHdyaXRpbmd9CmZ3cml0ZSh0ZW1wLCBmaWxlID0gcGFzdGUwKE9VVF9sb2MsICIvIiwgVG9kYXksICIuTksuREVHLlRhcmdldHMudHh0IiksCiAgICAgICBxdW90ZSA9IEZBTFNFLAogICAgICAgc2VwID0gIlx0IiwgCiAgICAgICBzaG93UHJvZ3Jlc3MgPSBGQUxTRSwgdmVyYm9zZSA9IEZBTFNFKQpgYGAKCgoKIyBTZXNzaW9uIGluZm9ybWF0aW9uCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKICAgIFZlcnNpb246ICAgICAgdjEuMi4wCiAgICBMYXN0IHVwZGF0ZTogIDIwMjQtMTAtMTcKICAgIFdyaXR0ZW4gYnk6ICAgU2FuZGVyIFcuIHZhbiBkZXIgTGFhbiAocy53LnZhbmRlcmxhYW4tMlthdF11bWN1dHJlY2h0Lm5sKS4KICAgIERlc2NyaXB0aW9uOiAgU2NyaXB0IHRvIGxvYWQgc2luZ2xlLWNlbGwgUk5BIHNlcXVlbmNpbmcgKHNjUk5Bc2VxKSBkYXRhLCBhbmQgcGVyZm9ybSBxdWFsaXR5IGNvbnRyb2wgKFFDKSwgYW5kIGluaXRpYWwgbWFwcGluZyB0byBjZWxscy4KICAgIE1pbmltdW0gcmVxdWlyZW1lbnRzOiBSIHZlcnNpb24gMy41LjIgKDIwMTgtMTItMjApIC0tICdFZ2dzaGVsbCBJZ2xvbycsIG1hY09TIE1vamF2ZSAoMTAuMTQuMikuCgogICAgKipNb1NDb1cgVG8tRG8gTGlzdCoqCiAgICBUaGUgdGhpbmdzIHdlIE11c3QsIFNob3VsZCwgQ291bGQsIGFuZCBXb3VsZCBoYXZlIGdpdmVuIHRoZSB0aW1lIHdlIGhhdmUuCiAgICBfTV8KCiAgICBfU18KCiAgICBfQ18KCiAgICBfV18KCiAgICAqKkNoYW5nZXMgbG9nKioKICAgICogdjEuMi4wIEZpeGVkIGFuIGlzc3VlIHdoZXJlIHRoZSBzdWJzZXQgb2Ygc2NSTkFzZXEgd2FzIGxvb3NpbmcgY2VsbC1pZGVudGl0aWVzLgogICAgKiB2MS4xLjEgVGV4dHVhbCBmaXhlcy4KICAgICogdjEuMS4xIEZpeCB3cml0aW5nIGJhc2VsaW5lIHRhYmxlLgogICAgKiB2MS4xLjAgVXBkYXRlIHRvIHN0dWR5IGRhdGFiYXNlLgogICAgKiB2MS4wLjIgRml4ZXMgdG8gdGhlIHN0YXJ0IG9mIHRoZSBub3RlYm9vay4gVXBkYXRlIHRvIGxvYWRpbmcgb2YgdGhlIGNsaW5pY2FsIGRhdGEuIEZpeCBvbiB0aGUgZ2VuZS1maWx0ZXJpbmcuCiAgICAqIHYxLjAuMSBVcGRhdGUgdG8gbWFpbiBBRURCICh0aGVyZSBpcyBhbiBlcnJvciBpbiB0aGUgQWdlLXZhcmlhYmxlIGluIHRoZSBuZXcgdmVyc2lvbikuIEZld2VyIHBhdGllbnRzIGluIHNjUk5Bc2VxICgzMiB2cyAzOSB3aXRoIHRoZSBuZXdlciBkYXRhc2V0KS4KICAgICogdjEuMC4wIEluaXRpYWwgdmVyc2lvbi4KCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpgYGB7ciBldmFsID0gVFJVRX0Kc2Vzc2lvbkluZm8oKQpgYGAKCiMgU2F2aW5nIGVudmlyb25tZW50CgpgYGB7ciBTYXZpbmd9CnJtKGJhY2t1cC5zY1JOQXNlcURhdGEpCnJtKHNjUk5Bc2VxRGF0YSwgc2NSTkFzZXFEYXRhQ0VBMzkpCgpzYXZlLmltYWdlKHBhc3RlMChQUk9KRUNUX2xvYywgIi8iLFRvZGF5LCIuIixQUk9KRUNUTkFNRSwiLkFFU0NSTkEucmVzdWx0cy5SRGF0YSIpKQoKYGBgCgorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rCnwgPHN1cD7CqSAxOTc5LTIwMjQgU2FuZGVyIFcuIHZhbiBkZXIgTGFhbiB8IHMudy52YW5kZXJsYWFuW2F0XWdtYWlsW2RvdF1jb20gfCBbdmFuZGVybGFhbmFuZC5zY2llbmNlXShodHRwczovL3ZhbmRlcmxhYW5hbmQuc2NpZW5jZSkuPC9zdXA+IHwKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKwoK